Question

I've created a JVMTI agent that does the following at a high level:

  • onClassLoadHook send the bytecodes for the loaded class to a separate Java process that will instrument the class using ASM

  • get the bytecodes back and load them

In my seperate java process that instruments the loaded Java class I do the following :

.. ..

    cr = new ClassReader(inBytes, offset, inLen);
    cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    ClassAdapter ca = new ClassAdapter(cw) {
    ..
    ..

        @Override
        public MethodVisitor visitMethod(final int access,
                                         final String name,
                                         final String desc,
                                         String signature,
                                         String[] exceptions) {

            return new MethodAdapter(mv) {

                @Override
                public void visitCode() {

                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/amir/Tester", "callTestStatic3", "(Ljava/lang/Object;)V");
                    mv.visitCode();

                }

            }
        }

When I try to decompile the class that is written after this instrumentation using Java Decompiler - I see the following decompiled function which I know is wrong :

  public void func1(int arg1, int arg2)
  {
    int b;
    Tester.callTestStatic3(???); 
    System.out.println("arg = " + a + " b = " + b);

  }

because my function actually looks like this :

public void func1(int a, int b) 
{

    System.out.println("arg = " +a + " b = " +b);

}

Can anyone tell me if I did something wrong here? My only clue is that if instead of passing in as an argument to my function the THIS pointer, if I pass in primitive types, everything works out finie. Is there something special about the THIS pointer that I need to manage? I've compared the bytecodes, and I've used ASMIFIER to get a clue as to what statements I need to use to generate the right bytecodes.

Was it helpful?

Solution

It looks like your code is correct, with mv.visitCode(). javap shows the expected bytecodes. I guess your original decompiler just wasn't doing the right thing.

OTHER TIPS

Perhaps it does not matter, but shouldn't you be calling super.visitCode()?

@Override
public void visitCode() {
  super.visitCode();
  ...

I'd use TraceClassVisitor to check exactly what was being generated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top