JPDA 架构研究16 - Agent利用环境指针访问VM(方法访问篇)

引入:

上文中我们讲解了Agent如何利用环境指针来访问VM的字段访问部分,现在来讲解方法访问部分。

分类11:方法访问

a.GetMethodName. 获取方法名字和签名

jvmtiError
GetMethodName(jvmtiEnv* env,
            jmethodID method,
            char** name_ptr,
            char** signature_ptr,
            char** generic_ptr)

b.GetMethodDeclaringClass.获取方法声明的类

jvmtiError
GetMethodDeclaringClass(jvmtiEnv* env,
            jmethodID method,
            jclass* declaring_class_ptr)

c.GetMethodModifiers. 获取方法的访问修饰符

jvmtiError
GetMethodModifiers(jvmtiEnv* env,
            jmethodID method,
            jint* modifiers_ptr)

d.GetMaxLocals.获取方法使用的局部变量

jvmtiError
GetMaxLocals(jvmtiEnv* env,
            jmethodID method,
            jint* max_ptr)

这个数值包含了方法入参中的变量数和方法体内用的局部变量数。

e.GetArgumentsSize. 获取方法的入参变量数

jvmtiError
GetArgumentsSize(jvmtiEnv* env,
            jmethodID method,
            jint* size_ptr)

f.GetLineNumberTable.获取某给定方法的行号表

typedef struct {
    jlocation start_location;
    jint line_number;
} jvmtiLineNumberEntry;
jvmtiError
GetLineNumberTable(jvmtiEnv* env,
            jmethodID method,
            jint* entry_count_ptr,
            jvmtiLineNumberEntry** table_ptr)

这个行号表来自于分析源代码

g.GetMethodLocation.  获取方法的位置

jvmtiError
GetMethodLocation(jvmtiEnv* env,
            jmethodID method,
            jlocation* start_location_ptr,
            jlocation* end_location_ptr)

h.GetLocalVariableTable.获取方法的本地变量列表。

typedef struct {
    jlocation start_location;
    jint length;
    char* name;
    char* signature;
    char* generic_signature;
    jint slot;
} jvmtiLocalVariableEntry;
jvmtiError
GetLocalVariableTable(jvmtiEnv* env,
            jmethodID method,
            jint* entry_count_ptr,
            jvmtiLocalVariableEntry** table_ptr)

i.GetByteCodes. 获取方法的字节码

jvmtiError
GetBytecodes(jvmtiEnv* env,
            jmethodID method,
            jint* bytecode_count_ptr,
            unsigned char** bytecodes_ptr)

j.IsMethodNative.判断某方法是否是native方法

jvmtiError
IsMethodNative(jvmtiEnv* env,
            jmethodID method,
            jboolean* is_native_ptr)

k.IsMethodSynthetic.判断某方法是否是合成方法

jvmtiError
IsMethodSynthetic(jvmtiEnv* env,
            jmethodID method,
            jboolean* is_synthetic_ptr)

所谓合成方法就是不出现在源代码中而是由编辑器创造出来的方法。

l.IsMethodObsolete.判断某方法是否是过时的方法。

jvmtiError
IsMethodObsolete(jvmtiEnv* env,
            jmethodID method,
            jboolean* is_obsolete_ptr)

判断该方法是否使用了一个过期的方法版本。

剩余还有一些JVMTI的函数,我就略去了。

时间: 2024-10-13 23:22:40

JPDA 架构研究16 - Agent利用环境指针访问VM(方法访问篇)的相关文章

JPDA 架构研究7 - Agent利用环境指针访问VM(线程组管理篇)

引入: 上篇文章中我们讨论了Agent利用环境指针访问VM的线程操作,这里讨论线程组操作. 分类3:线程组操作 a.GetTopThreadGroups.让Agent获取VM中的所有全局的线程组. jvmtiError GetTopThreadGroups(jvmtiEnv* env,             jint* group_count_ptr,             jthreadGroup** groups_ptr) 函数会返回全局的线程组的数量和线程组的列表. b.GetThre

JPDA 架构研究8 - Agent利用环境指针访问VM(堆栈管理篇)

引入: 上篇文章讲解了Agent利用环境指针访问VM的线程组操作,这里讨论下堆栈操作. 分类4:堆栈操作 a. GetStackTrace.获取某线程的堆栈. jvmtiError GetStackTrace(jvmtiEnv* env,             jthread thread,             jint start_depth,             jint max_frame_count,             jvmtiFrameInfo* frame_buff

JPDA 架构研究9 - Agent利用环境指针访问VM (堆管理篇)

引入: 上文中我们讨论了Agent利用环境指针访问VM的堆栈操作部分,这里我们讨论堆操作部分. 分类5:堆操作 a. GetTag. 获取对象在堆上的唯一标识符(长整型). jvmtiError GetTag(jvmtiEnv* env,             jobject object,             jlong* tag_ptr) b.SetTag.为对象设置堆上的唯一标示符. jvmtiError SetTag(jvmtiEnv* env,             jobje

JPDA 架构研究15 - Agent利用环境指针访问VM(字段访问篇)

引入: 上文中我们已经探讨了Agent如何利用环境指针访问VM(对象级的操作),现在我们 讨论让Agent利用环境指针访问类的字段. 分类10:字段访问 a.GetFieldName.获取某类的某字段名字 jvmtiError GetFieldName(jvmtiEnv* env,             jclass klass,             jfieldID field,             char** name_ptr,             char** signat

JPDA 架构研究13 - Agent利用环境指针访问VM(类管理篇)

引入: 上文中提到Agent如何利用环境指针访问VM的(Watch)功能,这里主要讲解如何去管理类的. 分类9:管理类 a.GetLoadedClasses. 获得虚拟机中所有被加载的类的数组. jvmtiError GetLoadedClasses(jvmtiEnv* env,             jint* class_count_ptr,               jclass** classes_ptr) 从返回值可以看出,class_count_ptr表示被加载的类的数量,cla

JPDA 架构研究10 - Agent利用环境指针访问VM(局部变量管理篇)

引入: 上篇我们讲解了Agent如何利用环境指针访问VM的管理堆的操作.这里主要讲解如何管理局部变量. 分类6:局部变量管理 a.GetLocalObject. 获取局部对象 jvmtiError GetLocalObject(jvmtiEnv* env,             jthread thread,             jint depth,             jint slot,             jobject* value_ptr) b.GetLocalInt.

JPDA 架构研究11 - Agent利用环境指针访问VM(断点操作篇)

引入: 上文我们讲解了Agent如何利用环境指针访问VM(操作局部变量篇),这里主要关注于如何操作断点. 这个在调试期间非常频繁的被使用. 分类7:断点操作 a.SetBreakPoint.设置断点,它会产生一个BreakPoint事件. jvmtiError SetBreakpoint(jvmtiEnv* env,             jmethodID method,             jlocation location) 设置断点指令.从这里可以看出需要传两个参数,一个是被设断

JPDA 架构研究12 - Agent利用环境指针访问VM(观察字段篇)

引入: 上文我们讲解了Agent如何利用环境指针访问VM的操作断点部分,这里我们详细讲解观察字段篇.这也是我们调试期间用的最多的操作.因为我们要不断从Watch Field看他们值的改变. 分类8:观察字段 a.SetFieldAccessWatch.启用对某字段进行访问的观察.每次访问都会创建一个FieldWatch事件. jvmtiError SetFieldAccessWatch(jvmtiEnv* env,             jclass klass,             jf

JPDA 架构研究14 - Agent利用环境指针访问VM(对象管理篇)

引入: 上文讨论了Agent如何利用环境指针访问VM(管理类),这里讨论如何管理对象. 分类9:对象管理 a.GetObjectSize.  获取对象的大小, jvmtiError GetObjectSize(jvmtiEnv* env,             jobject object,             jlong* size_ptr) 注意,这不是真实大小,这只是从对象的定义代码中获得的一个预估值. b.GetObjectHashCode.获取对象的hash值. jvmtiErr