From: Tom Tromey Date: Wed, 8 Apr 2020 20:33:35 +0000 (-0600) Subject: Add pending stop support to gdbserver's Windows port X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=360ad8b3505faea96190283270854bf9b397f334;p=binutils-gdb.git 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. gdbserver/ChangeLog 2020-04-08 Tom Tromey 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. --- diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 36d6f29e424..e75c475da45 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,10 @@ +2020-04-08 Tom Tromey + + 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. + 2020-04-08 Tom Tromey * win32-low.h (win32_process_target::stopped_by_sw_breakpoint) diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 4312bb3ab7c..e1226b4b0db 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -430,6 +430,10 @@ continue_one_thread (thread_info *thread, int thread_id) 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) @@ -1274,6 +1278,16 @@ get_child_debug_event (DWORD *continue_status, else #endif { + gdb::optional stop = fetch_pending_stop (debug_threads); + if (stop.has_value ()) + { + *ourstatus = stop->status; + current_event = stop->event; + ptid = debug_event_ptid (¤t_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. */ @@ -1377,7 +1391,7 @@ get_child_debug_event (DWORD *continue_status, ourstatus->value.sig = gdb_signal_from_host (exit_signal); } } - child_continue (DBG_CONTINUE, -1); + child_continue (DBG_CONTINUE, desired_stop_thread_id); CloseHandle (current_process_handle); current_process_handle = NULL; break; @@ -1437,7 +1451,21 @@ get_child_debug_event (DWORD *continue_status, } ptid = debug_event_ptid (¤t_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; } @@ -1486,7 +1514,7 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, /* fall-through */ case TARGET_WAITKIND_SPURIOUS: /* do nothing, just continue */ - child_continue (continue_status, -1); + child_continue (continue_status, desired_stop_thread_id); break; } }