通过 JVM TI 代理将 invokestatic 添加到 java/lang/Object.<init> 会导致 JVM 因段错误而崩溃
Adding invokestatic to java/lang/Object.<init> via JVM TI agent causes JVM to crash with segfault
我正在尝试跟踪 JVM 中所有对象的分配。
在有关分配分析器的几篇文档中提到最简单的方法是:
将invokestatic Tracker.trackAllocation()V
指令添加到java/lang/Object.<init>
(通常它由一条return
指令组成,我们在它之前添加invokestatic
,所以现在是2条指令)。
(我知道这种方法很慢并且不会跟踪数组分配,但我想从最简单的解决方案开始。而且我不会将对分配对象的引用传递给跟踪器,但这将在稍后添加。 )
Class 文件在 ClassLoaded 挂钩中使用 JVM TI 代理进行检测。
但是,在添加 invokestatic
指令后,JVM 因段错误而崩溃。
Tracker 对象被添加到 bootstrap classloader,因此它应该在任何阶段都可见。
我尝试添加 nop
而不是 invokestatic
,并且 JVM 可以很好地处理修改后的对象 class。所以问题出在某些静态方法的调用上。
我还尝试检测应用程序(不是基础的一部分)classes 并且它工作正常 - 跟踪器被调用并且没有发生崩溃。
我还尝试在 2 个点重新定义对象:当它最初加载时(第一次加载 class),或者在 vmInit 事件之后(当所有基础 classes 被加载并且对 jni 的限制被解除时)。
关于检测 java.lang.Object 我是否遗漏了什么?
代理代码在这里:
https://gist.github.com/Korobochka/3bf2f906f6ab85b22dec
(错误检查被删除,更改 classes 的代码也不包括在内,但它对其他 classes 来说已经足够好了)
看起来问题出在从 LeakAgentInterface 调用 System.out.println
时。首先,System.out
可能还没有初始化。其次,println
可以自己分配对象。
我正在尝试跟踪 JVM 中所有对象的分配。
在有关分配分析器的几篇文档中提到最简单的方法是:
将invokestatic Tracker.trackAllocation()V
指令添加到java/lang/Object.<init>
(通常它由一条return
指令组成,我们在它之前添加invokestatic
,所以现在是2条指令)。
(我知道这种方法很慢并且不会跟踪数组分配,但我想从最简单的解决方案开始。而且我不会将对分配对象的引用传递给跟踪器,但这将在稍后添加。 )
Class 文件在 ClassLoaded 挂钩中使用 JVM TI 代理进行检测。
但是,在添加 invokestatic
指令后,JVM 因段错误而崩溃。
Tracker 对象被添加到 bootstrap classloader,因此它应该在任何阶段都可见。
我尝试添加 nop
而不是 invokestatic
,并且 JVM 可以很好地处理修改后的对象 class。所以问题出在某些静态方法的调用上。
我还尝试检测应用程序(不是基础的一部分)classes 并且它工作正常 - 跟踪器被调用并且没有发生崩溃。 我还尝试在 2 个点重新定义对象:当它最初加载时(第一次加载 class),或者在 vmInit 事件之后(当所有基础 classes 被加载并且对 jni 的限制被解除时)。
关于检测 java.lang.Object 我是否遗漏了什么?
代理代码在这里: https://gist.github.com/Korobochka/3bf2f906f6ab85b22dec (错误检查被删除,更改 classes 的代码也不包括在内,但它对其他 classes 来说已经足够好了)
看起来问题出在从 LeakAgentInterface 调用 System.out.println
时。首先,System.out
可能还没有初始化。其次,println
可以自己分配对象。