private void InitializeAgentThread(JvmtiEnvironment environment, JniEnvironment nativeEnvironment) { _agentStartedEvent = new ManualResetEventSlim(false); _agentThread = CreateAgentThread(nativeEnvironment); _agentCallbackDelegate = AgentDispatcherThread; JvmtiErrorHandler.ThrowOnFailure(environment.RawInterface.RunAgentThread(environment, _agentThread, _agentCallbackDelegate, IntPtr.Zero, JvmThreadPriority.Maximum)); _agentStartedEvent.Wait(); }
private void HandleVMObjectAlloc(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jobject objectHandle, jclass objectClassHandle, long size) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jobject, jclass, long> method = HandleVMObjectAlloc; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle, objectHandle, objectClassHandle, size); return; } //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmObjectReference @object = JvmObjectReference.FromHandle(environment, jniEnv, objectHandle, true); //JvmClassReference objectClass = JvmClassReference.FromHandle(environment, jniEnv, objectClassHandle, true); //foreach (var processor in _processors) //{ // processor.HandleVMObjectAllocation(environment, thread, @object, objectClass, size); //} }
private void HandleVMInit(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle) { JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); JniEnvironment nativeEnvironment; if (AgentEventDispatcher == null) { if (VirtualMachine.IsAgentThread.Value) throw new InvalidOperationException(); nativeEnvironment = JniEnvironment.GetOrCreateInstance(jniEnv); VirtualMachine.HandleVMInit(environment, nativeEnvironment, threadHandle); InitializeAgentThread(environment, nativeEnvironment); } if (!VirtualMachine.IsAgentThread.Value) { // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread> method = HandleVMInit; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle); return; } JniErrorHandler.ThrowOnFailure(VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, false)); ThreadId threadId = VirtualMachine.TrackLocalThreadReference(threadHandle, environment, nativeEnvironment, false); bool sent = false; EventFilter[] filters = GetEventFilters(EventKind.VirtualMachineStart); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, default(TaggedReferenceTypeId), default(Location?))) { ApplySuspendPolicy(environment, nativeEnvironment, filter.SuspendPolicy, threadId); Callback.VirtualMachineStart(filter.SuspendPolicy, filter.RequestId, threadId); sent = true; } } if (!sent) { ApplySuspendPolicy(environment, nativeEnvironment, SuspendPolicy.All, threadId); Callback.VirtualMachineStart(SuspendPolicy.All, default(RequestId), threadId); } }
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); } } }
internal jvmtiError GetThreadInfo(jthread thread, out jvmtiThreadInfo threadInfo) { return RawInterface.GetThreadInfo(this, thread, out threadInfo); }
private void HandleClassLoad(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jclass classHandle) { //JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); //JniEnvironment nativeEnvironment; //JniErrorHandler.ThrowOnFailure(VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, false)); //VirtualMachine.HandleClassLoad(environment, nativeEnvironment, classHandle); }
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 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); } }
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); } } }
public jvmtiError GetLocalFloat(jthread thread, int depth, int slot, out float value) { return RawInterface.GetLocalFloat(this, thread, depth, slot, out value); }
public jvmtiError GetLocalDouble(jthread thread, int depth, int slot, out double value) { return RawInterface.GetLocalDouble(this, thread, depth, slot, out value); }
public jvmtiError GetLocalLong(jthread thread, int depth, int slot, out long value) { return RawInterface.GetLocalLong(this, thread, depth, slot, out value); }
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 GetFrameCount(jthread thread, out int frameCount) { return RawInterface.GetFrameCount(this, thread, out frameCount); }
private void HandleThreadEnd(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle) { /* This event is always sent on the thread that's starting. if it's an agent thread, just * ignore the event to hide it from the IDE. */ if (VirtualMachine.IsAgentThread.Value) return; // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread> method = HandleThreadEndImpl; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle); return; }
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); //} }
private void HandleThreadEndImpl(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle) { 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); EventFilter[] filters = GetEventFilters(EventKind.ThreadEnd); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, default(TaggedReferenceTypeId), default(Location?))) { ApplySuspendPolicy(environment, nativeEnvironment, filter.SuspendPolicy, threadId); Callback.ThreadDeath(filter.SuspendPolicy, filter.RequestId, threadId); } } }
private void HandleMethodExit(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, bool wasPoppedByException, jvalue returnValue) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jmethodID, bool, jvalue> method = HandleMethodExit; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle, methodId, wasPoppedByException, returnValue); return; } //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmMethod method = new JvmMethod(environment, methodId); //foreach (var processor in _processors) //{ // processor.HandleMethodExit(environment, thread, method, wasPoppedByException, returnValue); //} }
private void HandleClassPrepare(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jclass classHandle) { bool preventSuspend = VirtualMachine.IsAgentThread.Value; JvmtiEnvironment environment = JvmtiEnvironment.GetOrCreateInstance(_service.VirtualMachine, env); JniEnvironment nativeEnvironment = JniEnvironment.GetOrCreateInstance(jniEnv); string signature; IntPtr signaturePtr; IntPtr genericPtr; JvmtiErrorHandler.ThrowOnFailure(RawInterface.GetClassSignature(env, classHandle, out signaturePtr, out genericPtr)); try { unsafe { signature = ModifiedUTF8Encoding.GetString((byte*)signaturePtr); } } finally { RawInterface.Deallocate(env, signaturePtr); RawInterface.Deallocate(env, genericPtr); } ClassStatus classStatus = 0; jvmtiClassStatus internalClassStatus; JvmtiErrorHandler.ThrowOnFailure(RawInterface.GetClassStatus(env, classHandle, out internalClassStatus)); if ((internalClassStatus & jvmtiClassStatus.Error) != 0) classStatus |= ClassStatus.Error; if ((internalClassStatus & jvmtiClassStatus.Initialized) != 0) classStatus |= ClassStatus.Initialized; if ((internalClassStatus & jvmtiClassStatus.Prepared) != 0) classStatus |= ClassStatus.Prepared; if ((internalClassStatus & jvmtiClassStatus.Verified) != 0) classStatus |= ClassStatus.Verified; ThreadId threadId = VirtualMachine.TrackLocalThreadReference(threadHandle, environment, nativeEnvironment, false); TaggedReferenceTypeId classId = VirtualMachine.TrackLocalClassReference(classHandle, environment, nativeEnvironment, false); EventFilter[] filters = GetEventFilters(EventKind.ClassPrepare); foreach (var filter in filters) { if (filter.ProcessEvent(environment, nativeEnvironment, this, threadId, classId, default(Location?))) { SendClassPrepareEvent(environment, filter, threadId, classId, signature, classStatus, preventSuspend); } } }
private void HandleNativeMethodBind(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jmethodID methodId, IntPtr address, ref IntPtr newAddressPtr) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread //Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jmethodID, IntPtr, ReferenceTypeData intptr> method = HandleNativeMethodBind; //AgentEventDispatcher.Invoke(method, env, jniEnv); //return; throw new NotImplementedException(); } //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmMethod method = new JvmMethod(environment, methodId); //foreach (var processor in _processors) //{ // IntPtr? newAddress = null; // processor.HandleNativeMethodBind(environment, thread, method, address, ref newAddress); //} }
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); //} }
private void HandleMonitorContendedEntered(jvmtiEnvHandle env, JNIEnvHandle jniEnv, jthread threadHandle, jobject objectHandle) { if (!VirtualMachine.IsAgentThread.Value) { // ignore events before VMInit if (AgentEventDispatcher == null) return; // dispatch this call to an agent thread Action<jvmtiEnvHandle, JNIEnvHandle, jthread, jobject> method = HandleMonitorContendedEntered; AgentEventDispatcher.Invoke(method, env, jniEnv, threadHandle, objectHandle); return; } //JvmEnvironment environment = JvmEnvironment.GetEnvironment(env); //JvmThreadReference thread = JvmThreadReference.FromHandle(environment, jniEnv, threadHandle, true); //JvmObjectReference @object = JvmObjectReference.FromHandle(environment, jniEnv, objectHandle, true); //foreach (var processor in _processors) //{ // processor.HandleMonitorContendedEntered(environment, thread, @object); //} }
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 jvmtiError GetLocalObject(JniEnvironment nativeEnvironment, jthread thread, int depth, int slot, out TaggedObjectId value) { value = default(TaggedObjectId); jobject obj; jvmtiError error = RawInterface.GetLocalObject(this, thread, depth, slot, out obj); if (error != jvmtiError.None) return error; value = VirtualMachine.TrackLocalObjectReference(obj, this, nativeEnvironment, true); return jvmtiError.None; }