JDI、Java 字节码检测和 Java 代理(JWDP、JVMTI)

JDI, Java Byte code instrumentation and Java agents (JWDP, JVMTI)

我是调试器、仪器和 JVMTI 领域的新手。 所以我对他们的问题很少。

  1. JDI(java调试器接口)、JWDP、java代理和本机代理(JVMTI)之间有什么区别。 java 仪器 API 在图片中的位置。

  2. 我正在使用 JDI 拦截目标 java 应用程序中的异常。 但我发现如果我们谈论它如何影响目标应用程序的性能,JDI 还不够好。 我读到大多数优秀的应用程序都是通过将 JVMTI 与字节码检测相结合来做到这一点的。但我无法理解如何将字节码检测与 JVMTI 一起使用。 那么,我们如何与 JVMTI 一起进行字节码检测呢? 任何示例都会有所帮助。

  3. 我们可以在 java 中检测字节码和机器码吗?

  4. 静态字节码分析能否与JVMTI一起使用。如果是那么怎么办?

如果有任何问题不相关或错误,请告诉我。

1 - 我认为这个站点很好地解释了区别:http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/architecture.html - 这些基本上是相互叠加的 3 层抽象,JVMTI 直接与 运行 JVM 接口,然后 JDWP 被用作通信协议,然后 JDI 作为该远程 JVM 的接口。您可以使用 javaagent 来执行字节码检测(与这 3 件事的实现正交)。

2 - 我认为执行此操作的最有效方法是检测所有代码以在每个方法中添加一个 try/catch 来处理异常 - 当异常被捕获时,你处理它(但是你想要的),然后重新扔掉它。进行检测的最简单方法是使用 javaagent 方法(然后使用 javaassist 或 asm 或其他)。您也可以检测来自 JVMTI 的字节码,但它要麻烦得多。如果您只关心特定的异常(即那些显式抛出的异常,而不是解释器内部抛出的异常,如 NullPointerException、ArrayIndexOutOfBoundsException 等),那么处理这些异常的最简单方法是拦截 ATHROW 指令(指令用于抛出异常)。我没有具体经验,但创建一个为 Exception event 注册的 JVMTI 代理可能是合理的,但我不确定它的性能(可能和你的 JDI 方法一样慢,可能会更好) .

3 - 否:您只能在 Java 中检测字节码 运行。如果您想检测机器代码,您可以尝试使用诸如 pin 之类的东西来做到这一点,但我认为这对于您正在寻找的东西来说可能已经失控了。

4 - 当然:您对哪种静态分析感兴趣?您当然可以使用 soot 之类的东西,也可以使用 JVMTI。