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?
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
for methods where Stack is < 2 you need to bump it to 2.