Javassist's CtMethod.insertAt(line,src) instruments code at the wrong bytecode position

限于喜欢 提交于 2020-01-16 18:34:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!