【问题标题】:Javassist's CtMethod.insertAt(line,src) instruments code at the wrong bytecode positionJavassist 的 CtMethod.insertAt(line,src) 在错误的字节码位置检测代码
【发布时间】:2013-04-24 21:07:08
【问题描述】:

我的目标是在每个基本代码块的开头插入一点检测代码。使用 Javaassist 的 ControlFlow.Block 和 CtMethod.insertAt() 似乎是一项相当简单的任务。到目前为止,这是相关的代码块(它位于转换函数中):

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);
}

注意CtMethod.insertAt(line,srcCode)中的“line”参数是源代码行位置,而不是字节码行位置。在源代码中,一些基本块报告了相同的行号!这是输出:

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 # 代表我请求放置代码的位置,-> # 代表它在源代码中实际插入的位置(如果一切正常,它们应该是相同的)。 { ... } 中的所有内容都是我要放置的代码(_JDA_mse 是我使用 Javassist 方法添加到函数中的局部变量,因此使用它没有问题)。

问题在于for(int i=0; i<size; ++i) 包含多个在源代码中不可分割但在字节码中明显不同的基本块。这就是为什么多个基本块被映射到同一源代码行的原因,它只是表明源代码行没有提供足够的检测精度来记录基本块。 有没有办法模拟 CtMethod.insertAt(bytecodePosition,srcString) 而不是使用提供的 CtMethod.insertAt(sourceLine,srcString)?

【问题讨论】:

    标签: java instrumentation javassist javaagents


    【解决方案1】:

    如果您需要使用 Javaassist 插入的变量在字节码级别进行检测,请参阅this 解决方法。

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 2011-12-16
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多