What I want to do is to monitor the object creation and record a unique ID for that object.
Firstly I tried to monitor the NEW
instruction but it can not work and throw VerifyError: (...) Expecting to find object/array on stack
. I heard that the object after NEW
is uninitialized so it can not be passed to other methods. So I abandoned this approach.
Secondly, I tried to monitor the invocation of <init>
, this method initializes the uninitialized object. But I am not sure that after the initialization, if the initialized object will be pushed to the stack?
In my method visitor adapter:
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);
}
}
In MyRecorder.java
:
public static void object_new(Object ref){
log("object_new !");
log("MyRecorder: " + ref);
log("ref.getClass().getName(): " + ref.getClass().getName());
}
I tried them in a demo, it throws 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)
It seems not working as well. Are there any alternatives to monitor the object creation?