【发布时间】:2020-06-22 02:56:56
【问题描述】:
我想做的是监控对象的创建并为该对象记录一个唯一的 ID。
首先我尝试监视NEW 指令,但它无法工作并抛出VerifyError: (...) Expecting to find object/array on stack。听说NEW之后的对象是未初始化的,所以不能传给其他方法。所以我放弃了这种方法。
其次,我尝试监听<init>的调用,这个方法初始化了未初始化的对象。但是我不确定初始化之后,初始化的对象是否会被压栈?
在我的方法访问者适配器中:
public void visitMethodInsn(int opc, String owner, String name, String desc, boolean isInterface) {
...
mv.visitMethodInsn(opc, owner, name, desc, isInterface);
if (opc == INVOKESPECIAL && name.equals("<init>")) {
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESTATIC, "org/myekstazi/agent/PurityRecorder", "object_new",
"(Ljava/lang/Object;)V", false);
}
}
在MyRecorder.java:
public static void object_new(Object ref){
log("object_new !");
log("MyRecorder: " + ref);
log("ref.getClass().getName(): " + ref.getClass().getName());
}
我在演示中尝试过它们,它抛出VerifyError:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: Operand stack underflow
Exception Details:
Location:
AbstractDemo.<init>()V @4: dup
Reason:
Attempt to pop empty stack.
Current Frame:
bci: @4
flags: { }
locals: { 'AbstractDemo' }
stack: { }
Bytecode:
0x0000000: 2ab7 0001 59b8 003b b1
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetMethodRecursive(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
它似乎也无法正常工作。是否有其他方法可以监控对象创建?
【问题讨论】:
-
如果您可以使用其他工具,可以使用 Google 开发的库。 github.com/google/allocation-instrumenter
标签: java jvm instrumentation java-bytecode-asm javaagents