private void HandleSingleStep(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, jlocation jlocation) { JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); JniEnvironment nativeEnvironment = JniEnvironment.GetOrCreateInstance(jniEnv); ThreadId threadId = VirtualMachine.TrackLocalThreadReference(threadHandle, environment, nativeEnvironment, false); TaggedReferenceTypeId declaringClass; MethodId method = new MethodId(methodId.Handle); ulong index = (ulong)jlocation.Value; JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, method, out declaringClass)); Location location = new Location(declaringClass, method, index); EventFilter[] filters = GetEventFilters(EventKind.SingleStep); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, default(TaggedReferenceTypeId), location)) { SendSingleStepEvent(environment, filter, threadId, location); } } }
public JvmRemoteLocation(JvmMethodRemoteHandle method, jlocation location) { Method = method; Location = location; }
private void HandleException(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, jlocation jlocation, jobject exceptionHandle, jmethodID catchMethodId, jlocation catchjLocation) { // don't send exception events from an agent thread if (VirtualMachine.IsAgentThread.Value) return; JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); JniEnvironment nativeEnvironment = JniEnvironment.GetOrCreateInstance(jniEnv); TaggedReferenceTypeId declaringClass; MethodId method = new MethodId(methodId.Handle); ulong index = (ulong)jlocation.Value; JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, method, out declaringClass)); Location location = new Location(declaringClass, method, index); Location catchLocation; method = new MethodId(catchMethodId.Handle); index = (ulong)catchjLocation.Value; if (catchMethodId.Handle != IntPtr.Zero) { JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, method, out declaringClass)); catchLocation = new Location(declaringClass, method, index); } else { catchLocation = default(Location); } TaggedObjectId exceptionId = VirtualMachine.TrackLocalObjectReference(exceptionHandle, environment, nativeEnvironment, false); ThreadId threadId = VirtualMachine.TrackLocalThreadReference(threadHandle, environment, nativeEnvironment, false); EventFilter[] filters = GetEventFilters(EventKind.Exception); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, default(TaggedReferenceTypeId), location)) { SendExceptionEvent(environment, filter, threadId, location, exceptionId, catchLocation); } } ////Location location = new Location(); ////Location catchLocation = new Location(); //throw new NotImplementedException(); #if false ThreadId threadId = GetObjectId(ref threadHandle); TaggedObjectId exception = GetObjectId(ref exceptionHandle); EventFilter[] filters = GetEventFilters(EventKind.Exception); foreach (var filter in filters) { if (filter.ProcessEvent(threadId, default(TaggedReferenceTypeId))) { ApplySuspendPolicy(environment, filter.SuspendPolicy, threadId); Callback.HandleException(filter.SuspendPolicy, filter.RequestId, threadId, location, exception, catchLocation); } } #endif //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmLocation location = new JvmLocation(environment, method, jlocation); //JvmObjectReference exception = JvmObjectReference.FromHandle(environment, jniEnv, exceptionHandle, true); //JvmLocation catchLocation = new JvmLocation(environment, catchMethod, catchjLocation); //foreach (var processor in _processors) //{ // processor.HandleException(environment, thread, location, exception, catchLocation); //} }
private void HandleExceptionCatch(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, jlocation jlocation, jobject exceptionHandle) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jmethodID, jlocation, jobject> method = HandleExceptionCatch; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle, methodId, jlocation, exceptionHandle); return; } //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmLocation location = new JvmLocation(environment, method, jlocation); //JvmObjectReference exception = JvmObjectReference.FromHandle(environment, jniEnv, exceptionHandle, true); //foreach (var processor in _processors) //{ // processor.HandleExceptionCatch(environment, thread, location, exception); //} }
public Error SetEventInternal(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventKind eventKind, EventFilter filter) { EventRequestModifier locationModifier = default(EventRequestModifier); EventRequestModifier stepModifier = default(EventRequestModifier); switch (eventKind) { case EventKind.Breakpoint: // we're going to need the location modifier to set the breakpoint if (filter.Modifiers.Count == 0 || filter.Modifiers[0].Kind != ModifierKind.LocationFilter) return Error.IllegalArgument; locationModifier = filter.Modifiers[0]; break; case EventKind.SingleStep: // the first modifier contains the step properties if (filter.Modifiers.Count == 0 || filter.Modifiers[0].Kind != ModifierKind.Step) return Error.IllegalArgument; stepModifier = filter.Modifiers[0]; break; case EventKind.FramePop: if (filter.InternalEventKind == EventKind.SingleStep) goto case EventKind.SingleStep; break; default: break; } lock (_eventRequests) { Dictionary<RequestId, EventFilter> requests; if (!_eventRequests.TryGetValue(eventKind, out requests)) { requests = new Dictionary<RequestId, EventFilter>(); _eventRequests.Add(eventKind, requests); } requests.Add(filter.RequestId, filter); if (requests.Count == 1) { JvmEventType? eventToEnable = GetJvmEventType(eventKind); if (eventToEnable != null) { jvmtiError error = Environment.SetEventNotificationMode(JvmEventMode.Enable, eventToEnable.Value); if (error != jvmtiError.None) return GetStandardError(error); } } } switch (eventKind) { case EventKind.Breakpoint: { Contract.Assert(locationModifier.Kind == ModifierKind.LocationFilter); jmethodID methodId = locationModifier.Location.Method; jlocation location = new jlocation((long)locationModifier.Location.Index); jvmtiError error = Environment.SetBreakpoint(methodId, location); if (error != jvmtiError.None) return GetStandardError(error); break; } case EventKind.FramePop: if (filter.InternalEventKind == EventKind.SingleStep) { using (var thread = VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, stepModifier.Thread)) { if (!thread.IsAlive) return Error.InvalidThread; jvmtiError error = environment.RawInterface.NotifyFramePop(environment, thread.Value, 0); if (error != jvmtiError.None) return GetStandardError(error); } } break; default: break; } return Error.None; }
public Error ClearEventInternal(EventKind eventKind, RequestId requestId) { lock (_eventRequests) { Dictionary<RequestId, EventFilter> requests; if (!_eventRequests.TryGetValue(eventKind, out requests)) return Error.None; EventFilter eventFilter; if (!requests.TryGetValue(requestId, out eventFilter)) return Error.None; requests.Remove(requestId); if (requests.Count == 0) { JvmEventType? eventToDisable = GetJvmEventType(eventKind); if (eventToDisable != null) { jvmtiError error = Environment.SetEventNotificationMode(JvmEventMode.Disable, eventToDisable.Value); if (error != jvmtiError.None) return GetStandardError(error); } } if (eventKind == EventKind.Breakpoint) { LocationEventFilter locationFilter = eventFilter as LocationEventFilter; if (locationFilter == null) { AggregateEventFilter aggregateFilter = eventFilter as AggregateEventFilter; Contract.Assert(aggregateFilter != null); locationFilter = aggregateFilter.Filters.OfType<LocationEventFilter>().FirstOrDefault(); } Contract.Assert(locationFilter != null); jmethodID methodId = locationFilter.Location.Method; jlocation location = new jlocation((long)locationFilter.Location.Index); jvmtiError error = Environment.ClearBreakpoint(methodId, location); if (error != jvmtiError.None) return GetStandardError(error); } return Error.None; } }
private void HandleBreakpoint(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, jlocation jlocation) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jmethodID, jlocation> invokeMethod = HandleBreakpoint; AgentEventDispatcher.Invoke(invokeMethod, env, jniEnv, threadHandle, methodId, jlocation); return; } JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); JniEnvironment nativeEnvironment; JniErrorHandler.ThrowOnFailure(VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, false)); ThreadId threadId = VirtualMachine.TrackLocalThreadReference(threadHandle, environment, nativeEnvironment, false); TaggedReferenceTypeId declaringClass; MethodId method = new MethodId(methodId.Handle); ulong index = (ulong)jlocation.Value; JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, method, out declaringClass)); Location location = new Location(declaringClass, method, index); EventFilter[] filters = GetEventFilters(EventKind.Breakpoint); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, default(TaggedReferenceTypeId), location)) { ApplySuspendPolicy(environment, nativeEnvironment, filter.SuspendPolicy, threadId); Callback.Breakpoint(filter.SuspendPolicy, filter.RequestId, threadId, location); } } }
private void HandleFieldModification(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, jlocation jlocation, jclass fieldClassHandle, jobject objectHandle, jfieldID fieldId, byte signatureType, jvalue newValue) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jmethodID, jlocation, jclass, jobject, jfieldID, byte, jvalue> method = HandleFieldModification; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle, methodId, jlocation, fieldClassHandle, objectHandle, fieldId, signatureType, newValue); return; } //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmLocation location = new JvmLocation(environment, method, jlocation); //JvmClassReference fieldClass = JvmClassReference.FromHandle(environment, jniEnv, fieldClassHandle, true); //JvmObjectReference @object = JvmObjectReference.FromHandle(environment, jniEnv, objectHandle, true); //JvmField field = new JvmField(environment, fieldId); //foreach (var processor in _processors) //{ // processor.HandleFieldModification(environment, thread, location, fieldClass, @object, field, signatureType, newValue); //} }
internal jvmtiError ClearBreakpoint(jmethodID methodId, jlocation location) { return(RawInterface.ClearBreakpoint(this, methodId, location)); }
public jvmtiError GetMethodLocation(MethodId methodId, out jlocation startLocation, out jlocation endLocation) { return(RawInterface.GetMethodLocation(this, (jmethodID)methodId, out startLocation, out endLocation)); }
public jvmtiError GetFrameLocation(jthread thread, int depth, out jmethodID method, out jlocation location) { return(RawInterface.GetFrameLocation(this, thread, depth, out method, out location)); }
public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location) { if (!base.ProcessEvent(environment, nativeEnvironment, processor, thread, @class, location)) return false; // Step Out is implemented with Frame Pop events set at the correct depth if (_depth == StepDepth.Out) { if (location.HasValue && !location.Value.Method.Equals(_lastMethod)) { _lastLocation = new jlocation((long)location.Value.Index); _lastMethod = location.Value.Method; UpdateLastLine(environment); } return true; } using (var threadHandle = environment.VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, thread)) { int stackDepth; JvmtiErrorHandler.ThrowOnFailure(environment.GetFrameCount(threadHandle.Value, out stackDepth)); if (_hasMethodInfo && stackDepth > _stackDepth) { bool convertToFramePop; if (location.HasValue && (!_convertedToFramePop || !_framePopMethod.Equals(location.Value.Method)) && ShouldSkipCurrentMethod(processor.VirtualMachine, environment, nativeEnvironment, threadHandle.Value, stackDepth, location.Value, out convertToFramePop)) { if (convertToFramePop) { // remove the single step event JvmtiErrorHandler.ThrowOnFailure((jvmtiError)processor.ClearEventInternal(EventKind.FramePop, this.RequestId)); JvmtiErrorHandler.ThrowOnFailure((jvmtiError)processor.ClearEventInternal(EventKind.SingleStep, this.RequestId)); // set an actual step filter to respond when the thread arrives back in this frame JvmtiErrorHandler.ThrowOnFailure((jvmtiError)processor.SetEventInternal(environment, nativeEnvironment, EventKind.FramePop, this)); _convertedToFramePop = true; _framePopMethod = location.Value.Method; } return false; } else { _convertedToFramePop = false; return true; } } else if (stackDepth == _stackDepth) { if (_size == StepSize.Statement && _disassembledMethod != null) { int instructionIndex = _disassembledMethod.Instructions.FindIndex(i => (uint)i.Offset == location.Value.Index); if (instructionIndex >= 0 && _evaluationStackDepths != null && (_evaluationStackDepths[instructionIndex] ?? 0) != 0) { return false; } else if (instructionIndex >= 0 && _disassembledMethod.Instructions[instructionIndex].OpCode.FlowControl == JavaFlowControl.Branch) { // follow branch instructions before stopping return false; } } else if (_lastLine != null) { // see if we're on the same line LineNumberData[] lines; jvmtiError error = environment.GetLineNumberTable(location.Value.Method, out lines); if (error == jvmtiError.None) { LineNumberData entry = lines.LastOrDefault(i => i.LineCodeIndex <= (long)location.Value.Index); if (entry.LineNumber == _lastLine) return false; } } } if (location.HasValue) { _lastLocation = new jlocation((long)location.Value.Index); _lastMethod = location.Value.Method; UpdateLastLine(environment); } _stackDepth = stackDepth; return true; } }
internal jvmtiError ClearBreakpoint(jmethodID methodId, jlocation location) { return RawInterface.ClearBreakpoint(this, methodId, location); }
public jvmtiError GetFrameLocation(jthread thread, int depth, out jmethodID method, out jlocation location) { return RawInterface.GetFrameLocation(this, thread, depth, out method, out location); }
public jvmtiError GetMethodLocation(MethodId methodId, out jlocation startLocation, out jlocation endLocation) { return RawInterface.GetMethodLocation(this, (jmethodID)methodId, out startLocation, out endLocation); }