Reputation: 3269
Try to insert a log method with a String parameter, in this case, with e.getMessage()
on any catch Block of existing method.
The following snippets can inject a String.
...
CtMethod log = CtNewMethod.make("public void log(String s){ " +
" System.out.println(\"Hello from injected log method \" + s); " +
"}",
ct);
ct.addMethod(log);
...
ControlFlow cf = new ControlFlow(m);
Block blocks[] = cf.basicBlocks();
for(Block block : blocks){
Catcher catchers[] = block.catchers();
ArrayList<Catcher> catchersList = new ArrayList<Catcher>(Arrays.asList(catchers));
Collections.reverse(catchersList);
for (Catcher catcher : catchersList){
Block catchBlock = catcher.block();
int pos = catchBlock.position();
CodeIterator itr = m.getMethodInfo().getCodeAttribute().iterator();
Bytecode code = new Bytecode(m.getMethodInfo().getConstPool(), 0, 0);
code.addAload(0);
code.addLdc("LogParameter");
code.addInvokevirtual(ct,"log",log.getMethodInfo().getDescriptor());
code.addGap(2);
int n = itr.insertAt(pos,code.get());
m.getMethodInfo().rebuildStackMapForME(cp);
}
}
What i can't do is to get the e.getMessage()
as input parameter to log(String)
.
Maybe someone could point me in the right direction.
Upvotes: 1
Views: 541
Reputation: 43997
When you enter a catch block, you will find the exception lying on the stack. Thus, you can extract the message as follows:
duplicate the topmost value of the stack which is the exception such that you can call methods of this object without taking away the value for deeper instructions.
extract the message from the exception object by calling getMessage
virtually on it.
This way, you now have the exception message lying on top of the stack.
Upvotes: 1