RFR: JDK-8218701: jdb tests failed with AGENT_ERROR_INVALID_THREAD

Gary Adams gary.adams at oracle.com
Fri May 24 12:17:44 UTC 2019


I have not tracked down the specific root cause of this failure, yet.

It appears that the suspend is being attempted *before* the thread has been
recorded in *threadControl*.

Adding diagnostic messages is tricky because it changes the timing.
Here's a minimal probe to track threadControl addNode and clearThread
transactions. See attached log.txt.

diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c 
b/src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c
--- a/src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c
@@ -491,7 +491,9 @@
  static void
  suspendWithInvokeEnabled(jbyte policy, jthread thread)
  {
+  /*    if (threadControl_getInvokeRequest(thread) != NULL) { */
      invoker_enableInvokeRequests(thread);
+  /*    } */

      if (policy == JDWP_SUSPEND_POLICY(ALL)) {
          (void)threadControl_suspendAll();
diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c 
b/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c
--- a/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c
@@ -285,6 +285,7 @@
  static void
  addNode(ThreadList *list, ThreadNode *node)
  {
+  printf ("addNode %p \n", node->thread);
      node->next = NULL;
      node->prev = NULL;
      node->list = NULL;
@@ -362,6 +363,7 @@
  static void
  clearThread(JNIEnv *env, ThreadNode *node)
  {
+  printf("clearThread %p\n", node->thread);
      if (node->pendingStop != NULL) {
          tossGlobalRef(env, &(node->pendingStop));
      }
@@ -1646,6 +1648,8 @@
      node = findThread(&runningThreads, thread);
      if (node != NULL) {
           request = &node->currentInvoke;
+    } else {
+      printf ("threadControl_getInvokeRequest %p\n", thread);
      }

      debugMonitorExit(threadLock);

The AGENT_ERROR_INVALID_THREAD is reported when invoker_enableInvokeRequest
does not find the thread. I added the print out in 
threadControl_getInvokeRequest
when the thread is not found.

The workaround bypasses the error and falls through to the threadControl 
CommonSuspend
path where runningThreads is complimented with an otherThreads mechanism 
to ensure
threads that are not between start and end events will be properly 
resumed later on.


On 5/23/19, 1:23 PM, Chris Plummer wrote:
> Hi Gary,
>
> So a JVMTI event came in on a valid thread, got processed by the Debug 
> Agent and enqueued to be sent to the Debugger. However, before it was 
> actually sent, the thread became invalid. Am I understanding this 
> issue correctly?
>
> thanks,
>
> Chris
>
> On 5/23/19 2:59 AM, gary.adams at oracle.com wrote:
>> This proposed workaround ensures that the delay between a suspend 
>> request
>> passing through the jdwp command queue will not fail due to a no longer
>> running thread.
>>
>>   Webrev: http://cr.openjdk.java.net/~gadams/8218701/webrev/
>>   Issue: https://bugs.openjdk.java.net/browse/JDK-8218701
>>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20190524/7c362dc8/attachment.html>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: log.txt
URL: <https://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20190524/7c362dc8/log.txt>


More information about the serviceability-dev mailing list