java 代理中初始化 ThreadStart 事件回调和创建代理线程之间的竞争条件

Race condition in java agent between initializing ThreadStart event callback and agent threads being created

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

The VM initialization event signals the completion of VM initialization.

The thread start event for the main application thread is guaranteed not to occur until after the handler for the VM initialization event returns.

以及以下有关 ThreadStart 事件的信息:

Thread start events are generated by a new thread before its initial method executes.

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

作为旁注,如果代理线程在发送线程启动事件之前等待 VMMinit 完成,则等待 jdwp 服务器报告连接的 VMMinit 与等待 VMMinit 完成的 JDWP 服务器线程之间会发生死锁.

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

  1. 回调已注册 SetEventCallbacks
  2. 通知已打开 SetEventNotificationMode

以上调用的顺序并不重要。 SetEventCallbacksdocumentation 表示:

An event must be enabled and have a callback in order to be sent--the order in which this function and SetEventNotificationMode are called does not affect the result.

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

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