Java: adding debug call to every method with BCEL

1k Views Asked by At

I'm working with BCEL trying to add System.out.println() invoke to every method's first line (except init and clinit methods), to see what methods are called and when

This is my code atm (with some pseudo):

    Instruction ins = null;
    f (first instruction is ALOAD_0) {
       ins = get next instruction
    } else {
       ins = this instruction;
    }

    list.insert(ins, new GETSTATIC(cgen.getConstantPool().addFieldref("java/lang/System", "out", "Ljava/io/PrintStream;")));
    list.insert(ins, new LDC(cgen.getConstantPool().addUtf8("debug message")));
    list.insert(ins, new INVOKEVIRTUAL(cgen.getConstantPool().addMethodref("java/io/PrintStream", "println", "(Ljava/lang/String;)V")));

The edited class looks fine in bytecode but for some reason the class won't work after this. Is there something i'm doing wrong?

2

There are 2 best solutions below

1
On

you are pushing two arguments, and for some methods this might be larger than the max stack size for that method. You will need to adjust the max stack size for the method as well.

If you look at javap output you will see

Code:
    Stack=4, Locals=8, Args_size=3

for methods where Stack is < 2 you need to bump it to 2.

0
On

Problem solved, i was using .addUtf8 instead of .addString