5

有没有办法检测 JVM 引导阶段的结束?

编辑::

所以为了提供更多的上下文,我想做的是检测 JDK。这是一个完整的工具,可以记录每个 LOAD、STORE、INVOKE 字节码指令。随着指令的执行,它们的数据被发送到一个静态方法,该方法从 xbootclasspath 加载。此静态方法捕获所有这些信息并将所有这些信息存储为跟踪,以便以后执行分析。

现在,当我为 JDK 执行此操作时,我不想干扰类在 JVM 中的加载方式,这可能会导致程序崩溃。我猜测最好的方法是检测 JVM 完成引导的时间点,以便之后我可以安全地打开我的仪器。(我打算在进行引导时不检测任何代码。)这甚至是正确的方法吗?

4

1 回答 1

2

除了我之前关于调查FERRARIMAJOR的评论之外,我还想说几件事:

  • 这两个工具都只能作为已编译的 Java JAR 档案下载。
  • 所以我写信给今天创造这些工具的科学家,问他们我们的问题。一旦我收到答案,我会在这里报告。
  • 无论如何,我研究了 FERRARI 的架构,并认为我可能已经发现了他们是如何做到的。

因此,这是我对您可以做什么的有根据的猜测(仍未经过测试):

  • 检测您的 JDK 类。
  • 添加一个简单的类BootstrapLock,如下所述。
  • 将检测的 + 新类重新打包到修改后的rt.jar中。
  • 编写一个小的虚拟Java 代理,如下所述。
public class BootstrapLock {
    private static volatile boolean inBootstrap = true;

    public static boolean inBootstrap() {
        return inBootstrap;
    }

    public static synchronized void setEndOfBS() {
        inBootstrap = false;
    }
}

public class DummyAgent {
    public static void premain(String options, Instrumentation ins) {
        BootstrapLock.setEndOfBS();
    }
}

所以基本上逻辑如下:

  • 代理在主应用程序类之前加载,但在引导之后。
  • 因此,代理处于活动状态这一事实意味着引导已完成。
  • 因此代理可以关闭全局标记inBootstrap
  • 您的检测类可以检查标记以确定是否应该绕过它们的附加检测代码。

我不确定我是否有足够的时间来测试这个很快,但至少我想在这里发布这个答案,所以也许你,Vijai,也可以调查它并提供一些反馈。四只眼睛看到两个以上...


更新:法拉利的一位作者已经回答了我的询问并确认了我上面的解释。您可以只使用 java 代理作为 JVM 完成引导的标记。也许您甚至不需要额外的类,只需检查代理是否已加载到 JVM 中。它会让事情变得更简单,我只是不知道它是否表现良好。只是测试它。

于 2012-09-01T15:17:50.640 回答