使用Java中的ASM监视对象创建

Lif*_*ker 5 java instrumentation java-bytecode-asm

我正在使用ASM来监视Java中的对象创建.目前,我将调用init作为创建新对象的指示器并从中调整程序

invoke XXX.init
Run Code Online (Sandbox Code Playgroud)

dup;  
invoke XXX.init;  
call_my_method(Object)
Run Code Online (Sandbox Code Playgroud)

我的想法是复制newObjectReference的副本,并且在此对象的init之后,我调用我的方法来保留此对象.

但是,在运行时期间,有一个例外:

java.lang.VerifyError, Expecting to find unitialized object on stack.
Run Code Online (Sandbox Code Playgroud)

当我使用"-noverify"选项时,在运行时,如果有一个线程实例,则抛出第二个异常:

Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at test.ThreadTest.test
Run Code Online (Sandbox Code Playgroud)

对于第二种情况,我确信除了原始程序之外,没有调用线程的start().

有没有更好的方法来监控新对象的创建?

非常感谢.

vij*_*jay 4

尝试将 invoke XXX.init 转换为

invoke XXX.init;
dup;
call_my_method(Object)

基本上在 init 方法返回后调用重复项。

解释:: 因此,鉴于您想要跟踪新对象的创建,我猜您正在查看诸如new XXX()之类的语句。现在,将其转换为字节码的方式如下:-

NEW XXX
DUP
INVOKESPECIAL <init>

换句话说,NEW字节码指令用于创建对象本身。它被复制到堆栈顶部,因此您有该对象的附加副本。请注意,此时该对象的 2 个副本尚未初始化。然后在堆栈顶部的第一个未初始化对象上调用 init 方法。当构造函数返回时,该对象已初始化,因此位于堆栈顶部的对象也已初始化。(这是因为位于堆栈顶部的“对象”实际上是一个对象引用,指向位于堆上某处的实际对象。我使用“对象”一词而不是“对象引用”,因为这样更容易解释。如果这造成任何混乱,我们深表歉意。)