1

我正在开发一个项目,该项目将跟踪从包中的类到任何其他类的方法调用。重要的是我可以识别具体类型,并且我希望有一个最小的跟踪开销。触发探针的时间没有限制;它可以在调用方法之前或之后。

目前使用 ASM,但对它没有要求。该系统正在从 AspectJ 迁移,以允许动态连接,所以它已经过时了。

下面是目前的情况。'Tracer' 枚举/单例接收 probe(int) 并处理调用。找到从具体类型到引用类型的调用就足够了。

@Override
void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
    Integer probeID = Tracer.INSTANCE.probes.createProbeIDAt(new Call(owner, name, desc))

    super.visitFieldInsn(GETSTATIC, "org/flightofstairs/honours/capture/agent/Tracer", "INSTANCE", "Lorg/flightofstairs/honours/capture/agent/Tracer;");
    super.visitLdcInsn(probeID)
    super.visitMethodInsn(INVOKEVIRTUAL, "org/flightofstairs/honours/capture/agent/Tracer", "probe", "(Ljava/lang/Integer;)V")

    super.visitMethodInsn(opcode, owner, name, desc);
}

我更进一步的想法是以某种方式获取对被调用类的引用并调用 getClass() 来检索具体类型。如果堆栈包含 INVOKEINTERFACE 顶部的对象引用,这将是微不足道的,但被调用方法的任何参数都放在它上面。

考虑到参数的数量是已知的,计算对象引用的堆栈位置不会有问题,但是 java 无法从堆栈中的较低位置复制引用。

有什么建议吗?

干杯。

4

1 回答 1

0

一种解决方案是在遍历期间记录 INVOKEINTERFACE。最后,ASM 分析器可用于查找将 objectref 推入堆栈的指令,并从那里轻松添加 getClass() 和跟踪代码。

这里显示了一个解决方案。https://gist.github.com/2795738

于 2012-05-27T00:38:56.570 回答