diff mbox

[review] Add pending stop support to gdbserver's Windows port

Message ID gerrit.1574788288000.I8d2d24a55dc081887deebdd952dd6512ae23fa71@gnutoolchain-gerrit.osci.io
State New
Headers show

Commit Message

Simon Marchi (Code Review) Nov. 26, 2019, 5:11 p.m. UTC
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/724
......................................................................

Add pending stop support to gdbserver's Windows port

This changes gdbserver to also handle pending stops, the same way that
gdb does.  This is PR gdb/22992.

2019-11-26  Tom Tromey  <tromey@adacore.com>

	PR gdb/22992
	* win32-low.c (child_continue): Call matching_pending_stop.
	(get_child_debug_event): Call fetch_pending_stop.  Push pending
	stop when needed.

Change-Id: I8d2d24a55dc081887deebdd952dd6512ae23fa71
---
M gdb/gdbserver/ChangeLog
M gdb/gdbserver/win32-low.c
2 files changed, 38 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 9008bdc..a076a40 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,12 @@ 
 2019-11-26  Tom Tromey  <tromey@adacore.com>
 
+	PR gdb/22992
+	* win32-low.c (child_continue): Call matching_pending_stop.
+	(get_child_debug_event): Call fetch_pending_stop.  Push pending
+	stop when needed.
+
+2019-11-26  Tom Tromey  <tromey@adacore.com>
+
 	* win32-low.c (win32_supports_z_point_type): Always handle
 	Z_PACKET_SW_BP.
 	(win32_insert_point): Call insert_memory_breakpoint when needed.
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index c472e0e..f85fa23 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -430,6 +430,10 @@ 
 static BOOL
 child_continue (DWORD continue_status, int thread_id)
 {
+  desired_stop_thread_id = thread_id;
+  if (matching_pending_stop (debug_threads))
+    return TRUE;
+
   /* The inferior will only continue after the ContinueDebugEvent
      call.  */
   for_each_thread ([&] (thread_info *thread)
@@ -1261,6 +1265,16 @@ 
   else
 #endif
     {
+      gdb::optional<pending_stop> stop = fetch_pending_stop (debug_threads);
+      if (stop.has_value ())
+	{
+	  *ourstatus = stop->status;
+	  current_event = stop->event;
+	  ptid = debug_event_ptid (&current_event);
+	  current_thread = find_thread_ptid (ptid);
+	  return 1;
+	}
+
       /* Keep the wait time low enough for comfortable remote
 	 interruption, but high enough so gdbserver doesn't become a
 	 bottleneck.  */
@@ -1348,7 +1362,7 @@ 
 		(unsigned) current_event.dwThreadId));
       ourstatus->kind = TARGET_WAITKIND_EXITED;
       ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
-      child_continue (DBG_CONTINUE, -1);
+      child_continue (DBG_CONTINUE, desired_stop_thread_id);
       CloseHandle (current_process_handle);
       current_process_handle = NULL;
       break;
@@ -1408,7 +1422,21 @@ 
     }
 
   ptid = debug_event_ptid (&current_event);
-  current_thread = find_thread_ptid (ptid);
+
+  if (desired_stop_thread_id != -1 && desired_stop_thread_id != ptid.lwp ())
+    {
+      /* Pending stop.  See the comment by the definition of
+	 "pending_stops" for details on why this is needed.  */
+      OUTMSG2 (("get_windows_debug_event - "
+		"unexpected stop in 0x%x (expecting 0x%x)\n",
+		ptid.lwp (), desired_stop_thread_id));
+      maybe_adjust_pc ();
+      pending_stops.push_back ({(DWORD) ptid.lwp (), *ourstatus, current_event});
+      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+    }
+  else
+    current_thread = find_thread_ptid (ptid);
+
   return 1;
 }
 
@@ -1455,7 +1483,7 @@ 
 	  /* fall-through */
 	case TARGET_WAITKIND_SPURIOUS:
 	  /* do nothing, just continue */
-	  child_continue (continue_status, -1);
+	  child_continue (continue_status, desired_stop_thread_id);
 	  break;
 	}
     }