跟踪方法依赖于ASM

时间:2016-02-12 06:43:20

标签: java jvm bytecode java-bytecode-asm

我试图通过ASM跟踪方法依赖性。例如,假设我有这样的课程:

class Test{

  public void methodToRun(){
      Depedencies.startTracking();

      //method calls here 

      Depedencies.stopTracking();
  }

}

methodToRun被调用。由于我有Depedencies.startTracking()我需要开始打印所有方法调用详细信息,我仍然看到Depedencies.stopTracking()

我尝试使用以下代码通过ASM执行此操作:

public class ClassPrinter extends ClassVisitor {
   @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
          MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
          MethodAdapter adapter = new MethodAdapter(mv);
          return mv == null ? null : adapter;
    }
}

然后适配器看起来像这样:

class MethodAdapter extends MethodVisitor implements Opcodes {

    public MethodAdapter(final MethodVisitor mv) {
        super(ASM5, mv);
    }

    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {

        if(name.contains("startTracking")){
            System.out.println("Started tracking")
            TrackerState.startTrack();
        }else if(name.contains("stopTracking")) {
            System.out.println("End of tracking")
            TrackerState.stopTrack();
        }

        if(TrackerState.status())
        {
            //print the details.
        }

        mv.visitMethodInsn(opcode,owner,name,desc,itf);
    }

}

class TrackerState {
    private boolean static track = false;

    public static void startTrack(){
        track = true;
    }

    public static void stopTrack() {
        track = false;
    }

    public static boolean status() {
        return track
    }
}

上述ASM代码仅适用于一级方法调用跟踪。意思是,它没有跟踪方法是否调用另一个方法(我应该跟踪它),下面的代码解释了问题:

class Test {
    public void methodRunning()
    {
        Depedencies.startTracking();

        method1() //tracked , but method1's method calls doesnt get tracked
        method2() //tracked , , but method2's method calls doesnt get tracked and so on

        Depedencies.stopTracking();

        otherMethod() // not tracked as expected. 
    }
}

如何通过ASM处理此案例?

1 个答案:

答案 0 :(得分:1)

如果您想访问method1()method2()的内容,则需要使用您用来检查Test的相同技术单独访问它们。

如果有任何递归或继承,那可能会变得棘手。

在第一种情况下,问题在于找出停止条件(以避免无限递归),在第二种情况下,找出要访问的方法的具体实现。