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

时间:2012-10-18 09:09:35

标签: java instrumentation java-bytecode-asm

我正在使用ASM来监视Java中的对象创建。目前,我接受 init 的调用,作为创建新对象的指标,并从

中检测程序。
invoke XXX.init

dup;  
invoke XXX.init;  
call_my_method(Object)

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

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

java.lang.VerifyError, Expecting to find unitialized object on stack.

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

Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at test.ThreadTest.test

对于第二种情况,我确信除原始程序中的线程外,没有调用线程的启动()。

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

非常感谢。

1 个答案:

答案 0 :(得分:4)

尝试将Invoke XXX.init转换为

invoke XXX.init;
dup;
call_my_method(Object)

在init方法返回后,基本上调用副本。

说明::所以假设您想要跟踪新的对象创建,我猜您正在查看诸如 new XXX()之类的语句。现在,这转换为字节码的方式如下: -

NEW XXX
DUP
INVOKESPECIAL <init>

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