5

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

invoke XXX.init

dup;  
invoke XXX.init;  
call_my_method(Object)

我的想法是复制一个 newObjectReference 的副本,并且在这个对象的初始化之后,我调用我的方法来保留这个对象。

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

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

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

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

非常感谢。

4

1 回答 1

4

尝试,将调用 XXX.init 转换为

invoke XXX.init;
dup;
call_my_method(Object)

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

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

NEW XXX
DUP
INVOKESPECIAL <init>

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

于 2012-10-19T07:00:04.337 回答