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 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); } } }
private void WriteLocation(byte[] data, int offset, Location location) { data[offset] = (byte)location.TypeTag; WriteReferenceTypeId(data, sizeof(byte), location.Class); WriteMethodId(data, sizeof(byte) + ReferenceTypeIdSize, location.Method); WriteInt64(data, sizeof(byte) + ReferenceTypeIdSize + MethodIdSize, (long)location.Index); }
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 bool ShouldSkipCurrentMethod(JavaVM virtualMachine, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jthread thread, int stackDepth, Location location, out bool convertToFramePop) { Contract.Assert(_depth == StepDepth.Into || _depth == StepDepth.Over); convertToFramePop = false; if (!_hasMethodInfo || stackDepth < _stackDepth || (stackDepth == _stackDepth && (location.Method.Equals(_lastMethod)))) return false; /* * change this to a Frame Pop event if we're not in a native frame */ bool native; jvmtiError error = environment.IsMethodNative(location.Method, out native); if (error != jvmtiError.None) return false; convertToFramePop = !native; if (_depth == StepDepth.Over || native) return true; JvmAccessModifiers modifiers; error = environment.GetMethodModifiers(location.Method, out modifiers); if (error != jvmtiError.None || ((modifiers & JvmAccessModifiers.Static) != 0)) return false; jobject thisObject; error = environment.GetLocalObject(thread, 0, 0, out thisObject); if (error != jvmtiError.None) return false; try { bool classLoader = nativeEnvironment.IsInstanceOf(thisObject, virtualMachine.ClassLoaderClass); if (!classLoader) return false; string name; string signature; string genericSignature; error = environment.GetMethodName(location.Method, out name, out signature, out genericSignature); if (error != jvmtiError.None) return false; if (name == "loadClass" && signature == "(Ljava/lang/String;)Ljava/lang/Class;") return true; if (name == "checkPackageAccess" && signature == "(Ljava/lang/Class;Ljava/security/ProtectionDomain;)V") return true; return false; } finally { nativeEnvironment.DeleteLocalReference(thisObject); } }
public abstract bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location);
public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location) { return true; }
public static EventRequestModifier LocationFilter(Location location) { return new EventRequestModifier() { Kind = ModifierKind.LocationFilter, Location = location, }; }
public LocationEventFilter(EventKind internalEventKind, RequestId requestId, SuspendPolicy suspendPolicy, IEnumerable<EventRequestModifier> modifiers, Location location) : base(internalEventKind, requestId, suspendPolicy, modifiers) { _location = location; }
public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location) { if (!location.HasValue) return false; return _location.Index == location.Value.Index && _location.Class == location.Value.Class && _location.Method == location.Value.Method; }
public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location) { _current++; if (_current == _count) { _current = 0; return true; } return false; }
public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location) { foreach (EventFilter filter in _filters) { if (!filter.ProcessEvent(environment, nativeEnvironment, processor, thread, @class, location)) return false; } return true; }
public jvmtiError GetStackTrace(JniEnvironment nativeEnvironment, ThreadId threadId, int startDepth, int maxFrameCount, out FrameLocationData[] frames) { frames = null; using (var thread = VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, threadId)) { if (!thread.IsAlive) return jvmtiError.InvalidThread; jvmtiFrameInfo[] frameBuffer = new jvmtiFrameInfo[maxFrameCount]; int frameCount; jvmtiError error = RawInterface.GetStackTrace(this, thread.Value, startDepth, maxFrameCount, frameBuffer, out frameCount); if (error != jvmtiError.None) return error; var frameData = new FrameLocationData[frameCount]; for (int i = 0; i < frameCount; i++) { TaggedReferenceTypeId declaringClass; MethodId method = new MethodId(frameBuffer[i]._method.Handle); ulong index = (ulong)frameBuffer[i]._location.Value; error = GetMethodDeclaringClass(nativeEnvironment, method, out declaringClass); if (error != jvmtiError.None) return error; FrameId frameId = new FrameId(startDepth + i); Location location = new Location(declaringClass, method, index); frameData[i] = new FrameLocationData(frameId, location); } frames = frameData; return jvmtiError.None; } }
private void SendSingleStepEvent(JvmtiEnvironment environment, EventFilter filter, ThreadId threadId, Location location) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<JvmtiEnvironment, EventFilter, ThreadId, Location> invokeMethod = SendSingleStepEvent; AgentEventDispatcher.Invoke(invokeMethod, environment, filter, threadId, location); return; } JniEnvironment nativeEnvironment; JniErrorHandler.ThrowOnFailure(VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, false)); ApplySuspendPolicy(environment, nativeEnvironment, filter.SuspendPolicy, threadId); Callback.SingleStep(filter.SuspendPolicy, filter.RequestId, threadId, 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; } }
private void HandleFramePop(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, bool wasPoppedByException) { try { JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); JniEnvironment nativeEnvironment = JniEnvironment.GetOrCreateInstance(jniEnv); TaggedReferenceTypeId declaringClass; MethodId method = new MethodId(methodId.Handle); jlocation jlocation; JvmtiErrorHandler.ThrowOnFailure(environment.GetFrameLocation(threadHandle, 1, out methodId, out jlocation)); ulong index = (ulong)jlocation.Value; JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, method, out declaringClass)); Location location = new Location(declaringClass, method, index); ThreadId threadId = VirtualMachine.TrackLocalThreadReference(threadHandle, environment, nativeEnvironment, false); EventFilter[] filters = GetEventFilters(EventKind.FramePop); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, default(TaggedReferenceTypeId), location)) { if (filter.InternalEventKind == EventKind.SingleStep) { // remove the frame pop event JvmtiErrorHandler.ThrowOnFailure((jvmtiError)ClearEventInternal(EventKind.FramePop, filter.RequestId)); // set an actual step filter to respond when the thread arrives in the parent frame JvmtiErrorHandler.ThrowOnFailure((jvmtiError)SetEventInternal(environment, nativeEnvironment, EventKind.SingleStep, filter)); } else { SendFramePopEvent(environment, filter, threadId, location, wasPoppedByException); } } } } catch (Exception e) { string caption = "Exception while handling a frame pop event"; System.Windows.Forms.MessageBox.Show(e.Message + System.Environment.NewLine + System.Environment.NewLine + e.StackTrace, caption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); throw; } }
public FrameLocationData(FrameId frameId, Location location) { FrameId = frameId; Location = location; }