【问题标题】:Race condition in java agent between initializing ThreadStart event callback and agent threads being created初始化 ThreadStart 事件回调和创建代理线程之间的 Java 代理中的竞争条件
【发布时间】:2020-07-08 05:27:27
【问题描述】:

JVMTI 文档说明了以下有关 VMInit 事件的内容。

VM 初始化事件表示 VM 初始化完成。

主应用程序线程的线程启动事件保证在虚拟机初始化事件的处理程序返回之前不会发生。

还有以下关于 ThreadStart 事件:

线程启动事件由新线程在其初始方法执行之前生成。

我正在观察一个 openjdk-8 java 代理(特别是 libjdwp.so),启用线程启动事件,使用 RunAgentThread 启动线程,然后在 VMInit 处理程序期间使用 SetEventCallbacks 设置线程启动回调。虽然需要在 VMInit 处理程序完成后发生主线程启动事件,但代理线程事件则不需要。这意味着代理线程可以触发没有回调的线程启动事件。这是预期的行为吗?未设置事件回调但已启用时的 VM 行为是否已定义?如果有,它是怎么定义的?

附带说明,如果代理线程在发送线程启动事件之前等待 VMInit 完成,则在等待 jdwp 服务器报告连接的 VMInit 和等待 VMInit 完成的 JDWP 服务器线程之间会发生死锁。

【问题讨论】:

    标签: java jvm race-condition javaagents jvmti


    【解决方案1】:

    JVM TI events 仅在满足这两个条件时发送:

    1. 回调注册到SetEventCallbacks
    2. 使用SetEventNotificationMode 打开通知

    上述调用的顺序并不重要。 documentation for SetEventCallbacks 说:

    一个事件必须被启用并且有一个回调才能被发送—— 调用此函数和 SetEventNotificationMode 的顺序 不影响结果。

    可以在不设置回调的情况下启用通知事件。在这种情况下,JVM 不会发送事件。

    我认为 jdwp 代理行为没有问题。如果代理对接收有关自己线程的通知不感兴趣,它可以稍后在VMInit 处理程序中设置回调。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-23
      • 2016-11-16
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多