diff options
-rw-r--r-- | gdbserver/ChangeLog | 7 | ||||
-rw-r--r-- | gdbserver/win32-low.cc | 34 |
2 files changed, 38 insertions, 3 deletions
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 36d6f29..e75c475 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,5 +1,12 @@ 2020-04-08 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. + +2020-04-08 Tom Tromey <tromey@adacore.com> + * win32-low.h (win32_process_target::stopped_by_sw_breakpoint) (win32_process_target::supports_stopped_by_sw_breakpoint): Declare. diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 4312bb3..e1226b4 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<pending_stop> 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; } } |