问题
My goal is to insert a little bit of instrumentation code at the beginning of each basic block of code. It seems like a fairly simple task with Javaassist's ControlFlow.Block and CtMethod.insertAt(). Here's the relevant chunk of code so far (it's located in the transform function):
ControlFlow flow=new ControlFlow(m); //m is the CtMethod currently being instrumented
Block[] blockArray=flow.basicBlocks();
for(Block thisbb : blockArray){
//Dynamically Update Method Statistics
String blockUpdate=new String();
String thisbbIndex=Integer.toString(thisbb.index());
blockUpdate+=mse+".setBlockIndex("+thisbbIndex+"); ";
blockUpdate="{ " + blockUpdate + "} ";
//Insert
int pos=m.getMethodInfo().getLineNumber(thisbb.position()); //Source code line position from binary line position
System.out.print("At "+pos+": "+blockUpdate);
int n=m.insertAt(pos, blockUpdate);
System.out.println(" -> "+n);
}
Note that the "line" parameter in CtMethod.insertAt(line,srcCode)
is the source code line position, not the bytecode line position. In the source code, some basic blocks are reporting the same line number! Here is the output:
At 6: { _JDA_mse.setBlockIndex(0); } -> 6
At 8: { _JDA_mse.setBlockIndex(1); } -> 8
At 8: { _JDA_mse.setBlockIndex(2); } -> 8
At 8: { _JDA_mse.setBlockIndex(3); } -> 8
At 8: { _JDA_mse.setBlockIndex(4); } -> 8
At 8: { _JDA_mse.setBlockIndex(5); } -> 8
At 8: { _JDA_mse.setBlockIndex(6); } -> 8
At #
represents the location that I requested the code to be placed at, and the -> #
represents the location in the source code that it was actually inserted (if everything works out, they should be the same). Everything inside the { ... }
is the code that I want placed (_JDA_mse
is a local variable that I added to the function with Javassist methods, so there's no problem in using it).
The issue is that for(int i=0; i<size; ++i)
contains multiple basic blocks that are inseparable in the source code but clearly distinct in the bytecode. This is why multiple basic blocks are being mapped to the same source line, and it just shows that source code lines do not provide sufficient instrumentation accuracy to log basic blocks. Is there a way to emulate a CtMethod.insertAt(bytecodePosition,srcString) instead of using the provided CtMethod.insertAt(sourceLine,srcString)?
回答1:
See this work around if you need to instrument at the bytecode level using variables that were inserted by Javaassist.
来源:https://stackoverflow.com/questions/16202204/javassists-ctmethod-insertatline-src-instruments-code-at-the-wrong-bytecode-p