在正常执行之前,我需要检测本机方法以进行简单的静态调用。因为这些方法是原生的,所以我必须使用“setNativePrefix”功能,并使用带有原始方法签名的中间调用来包装原生方法。
在我认为是一个简单的字节码更改来完成此操作之后,即使堆栈基本上是空的,我也会在包装方法执行之前得到一个 StackOverflowError 。这是我的测试课:
public class SimpleTest {
public static void main(String[] args) throws IOException {
Perf.getPerf().highResCounter();
}
}
通常,该程序不会在控制台上产生任何结果。但是,我的检测字节码在执行本机方法 $wrapper$highResCounter() 之前执行 println()。这可以在检测后的相关 Perf 类字节码中看到:
public long highResCounter() {
getstatic PrintStream System.out
ldc String Constant "this is an instrumented println"
invokevirtual void PrintStream.println(String)
aload 0
invokevirtual long Perf.$wrapped$highResCounter()
lreturn
}
public native long $wrapped$highResCounter();
我对 Java 字节码有点陌生,所以我可能在这里犯了一个错误。这是程序的输出,它显示 println() 被执行,但是在第一次 invokevirtual调用之后的某个地方抛出了 StackOverflowError:
this is an instrumented println call
Exception in thread "main" java.lang.StackOverflowError
at com.foo.SimpleTest.main(SimpleTest.java:17)
什么可能导致此 StackOverflowError?我该如何解决?