johnh
johnh

Reputation: 21

Java: adding debug call to every method with BCEL

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?

Upvotes: 1

Views: 1028

Answers (2)

johnh
johnh

Reputation: 21

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

Upvotes: 1

MeBigFatGuy
MeBigFatGuy

Reputation: 28598

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.

Upvotes: 1

Related Questions