public void Dispose() { if (IsAlive) { _nativeEnvironment.DeleteLocalReference(_reference); } }
internal TaggedReferenceTypeId TrackLocalClassReference(jclass classHandle, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference) { if (classHandle == jclass.Null) { return(default(TaggedReferenceTypeId)); } bool isArrayClass; JvmtiErrorHandler.ThrowOnFailure(environment.IsArrayClass(classHandle, out isArrayClass)); bool isInterface; JvmtiErrorHandler.ThrowOnFailure(environment.IsInterface(classHandle, out isInterface)); TypeTag typeTag = isArrayClass ? TypeTag.Array : (isInterface ? TypeTag.Interface : TypeTag.Class); int hashCode; JvmtiErrorHandler.ThrowOnFailure(environment.GetObjectHashCode(classHandle, out hashCode)); ReferenceTypeId typeId = new ReferenceTypeId(hashCode); TaggedReferenceTypeId taggedTypeId = new TaggedReferenceTypeId(typeTag, typeId); lock (_classes) { if (!_classes.ContainsKey(typeId)) { jweak weak = nativeEnvironment.NewWeakGlobalReference(classHandle); bool added = false; if (!_classes.ContainsKey(typeId)) { _classes.Add(typeId, new jclass(weak.Handle)); added = true; } if (!added) { nativeEnvironment.DeleteWeakGlobalReference(weak); } } } if (freeLocalReference) { nativeEnvironment.DeleteLocalReference(classHandle); } return(taggedTypeId); }
internal void HandleVMInit(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jthread thread) { jclass threadClass = nativeEnvironment.GetObjectClass(thread); _threadClass = FindBaseClass(environment, nativeEnvironment, threadClass, "Ljava/lang/Thread;"); { jclass classClass = nativeEnvironment.GetObjectClass(threadClass); _classClass = FindBaseClass(environment, nativeEnvironment, classClass, "Ljava/lang/Class;"); nativeEnvironment.DeleteLocalReference(classClass); } { jvmtiThreadInfo threadInfo; JvmtiErrorHandler.ThrowOnFailure(environment.GetThreadInfo(thread, out threadInfo)); jclass threadGroupClass = nativeEnvironment.GetObjectClass(threadInfo._threadGroup); _threadGroupClass = FindBaseClass(environment, nativeEnvironment, threadGroupClass, "Ljava/lang/ThreadGroup;"); jclass classLoaderClass = nativeEnvironment.GetObjectClass(threadInfo._contextClassLoader); _classLoaderClass = FindBaseClass(environment, nativeEnvironment, classLoaderClass, "Ljava/lang/ClassLoader;"); nativeEnvironment.DeleteLocalReference(classLoaderClass); nativeEnvironment.DeleteLocalReference(threadGroupClass); nativeEnvironment.DeleteLocalReference(threadInfo._contextClassLoader); nativeEnvironment.DeleteLocalReference(threadInfo._threadGroup); environment.Deallocate(threadInfo._name); } nativeEnvironment.DeleteLocalReference(threadClass); jobject stringObject = nativeEnvironment.NewString(string.Empty); jclass stringClass = nativeEnvironment.GetObjectClass(stringObject); _stringClass = FindBaseClass(environment, nativeEnvironment, stringClass, "Ljava/lang/String;"); nativeEnvironment.DeleteLocalReference(stringObject); nativeEnvironment.DeleteLocalReference(stringClass); }
internal ThreadId TrackLocalThreadReference(jthread thread, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference) { if (thread == jthread.Null) { return(default(ThreadId)); } int hashCode; JvmtiErrorHandler.ThrowOnFailure(environment.RawInterface.GetObjectHashCode(environment, thread, out hashCode)); ThreadId threadId = new ThreadId(hashCode); lock (_threads) { if (!_threads.ContainsKey(threadId)) { jweak weak = nativeEnvironment.NewWeakGlobalReference(thread); bool added = false; if (!_threads.ContainsKey(threadId)) { _threads.Add(threadId, new jthread(weak.Handle)); added = true; } if (!added) { nativeEnvironment.DeleteWeakGlobalReference(weak); } } } if (freeLocalReference) { nativeEnvironment.DeleteLocalReference(thread); } return(threadId); }
internal jclass FindBaseClass(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jclass classHandle, string signature) { string currentSignature; string genericSignature; JvmtiErrorHandler.ThrowOnFailure(environment.GetClassSignature(classHandle, out currentSignature, out genericSignature)); if (currentSignature == signature) { return((jclass)nativeEnvironment.NewGlobalReference(classHandle)); } jclass superClass = nativeEnvironment.GetSuperclass(classHandle); if (superClass == jclass.Null) { return(jclass.Null); } jclass result = FindBaseClass(environment, nativeEnvironment, superClass, signature); nativeEnvironment.DeleteLocalReference(superClass); return(result); }
private jthread CreateAgentThread(JniEnvironment nativeEnvironment) { jclass @class = nativeEnvironment.FindClass("java/lang/Thread"); if (@class == jclass.Null) throw new Exception("ERROR: JNI: Cannot find java/lang/Thread with FindClass."); jmethodID method = nativeEnvironment.GetMethodId(@class, "<init>", "()V"); if (method == jmethodID.Null) throw new Exception("Cannot find Thread constructor method."); jthread result = (jthread)nativeEnvironment.NewObject(@class, method); if (result == jthread.Null) throw new Exception("Cannot create new Thread object"); jthread agentThread = (jthread)nativeEnvironment.NewGlobalReference(result); if (result == jthread.Null) throw new Exception("Cannot create a new global reference for the agent thread."); // don't need to keep the local reference around nativeEnvironment.DeleteLocalReference(result); return agentThread; }
internal TaggedObjectId TrackLocalObjectReference(jobject @object, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference) { if (@object == jobject.Null) { return(new TaggedObjectId(Tag.Object, new ObjectId(0), default(TaggedReferenceTypeId))); } long tag; JvmtiErrorHandler.ThrowOnFailure(environment.GetTag(@object, out tag)); TaggedReferenceTypeId type = default(TaggedReferenceTypeId); Tag objectKind; if (tag == 0) { long uniqueTag = Interlocked.Increment(ref _nextTag); /* first figure out what type of object we're dealing with. could be: * - String * - Thread * - ThreadGroup * - ClassLoader * - ClassObject * - Array * - Object */ // check for array jclass objectClass = nativeEnvironment.GetObjectClass(@object); try { type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, false); bool isArray = type.TypeTag == TypeTag.Array; if (isArray) { objectKind = Tag.Array; } else { if (_stringClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _stringClass)) { objectKind = Tag.String; } else if (_threadClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadClass)) { objectKind = Tag.Thread; } else if (_threadGroupClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadGroupClass)) { objectKind = Tag.ThreadGroup; } else if (_classClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classClass)) { objectKind = Tag.ClassObject; } else if (_classLoaderClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classLoaderClass)) { objectKind = Tag.ClassLoader; } else { objectKind = Tag.Object; } } } finally { nativeEnvironment.DeleteLocalReference(objectClass); } tag = (uniqueTag << 8) | (uint)objectKind; JvmtiErrorHandler.ThrowOnFailure(environment.SetTag(@object, tag)); lock (_objects) { _objects.Add(new ObjectId(tag), nativeEnvironment.NewWeakGlobalReference(@object)); } } else { jclass objectClass = nativeEnvironment.GetObjectClass(@object); type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, true); } if (freeLocalReference) { nativeEnvironment.DeleteLocalReference(@object); } objectKind = (Tag)(tag & 0xFF); return(new TaggedObjectId(objectKind, new ObjectId(tag), type)); }
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); } }