[PATCH v2 14/47] Windows gdb: Simplify windows_nat_target::wait

Pedro Alves
2025-05-19T13:28:42Z

The logic in windows_nat_target::wait, where we decide what to do
depending on the result from get_windows_debug_event is harder to
grasp than it looks.

It is not easy to tell what should happen when in async mode
get_windows_debug_event returns that there's no event to process.

And then, if get_windows_debug_event returns null_ptid /
TARGET_WAITKIND_SPURIOUS, then we need to issue a ContinueDebugEvent.

There's also this comment in windows_nat_target::wait, which we're not
really implementing today:

~~~~
/* We loop when we get a non-standard exception rather than return
with a SPURIOUS because resume can try and step or modify things,
which needs a current_thread->h. But some of these exceptions mark
the birth or death of threads, which mean that the current thread
isn't necessarily what you think it is. */
~~~~

This patch changes things a bit so that the code is more obvious:

- look at the status kind, instead of ptid_t.

- add an explicit early return case for no-event.

- add an explicit case for TARGET_WAITKIND_SPURIOUS.

- with those, we no longer need to handle the case of find_thread not
finding a thread, so we can drop one indentation level.

Change-Id: I76c41762e1f893a7ff23465856ccf6a44af1f0e7
---
gdb/windows-nat.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index f15b7520296..9b8bb66d700 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1661,7 +1661,10 @@ windows_nat_target::get_windows_debug_event
}

if (thread_id == 0)
- return null_ptid;
+ {
+ ourstatus->set_ignore ();
+ return null_ptid;
+ }
return ptid_t (windows_process.current_event.dwProcessId, thread_id, 0);
}

@@ -1682,27 +1685,33 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
{
ptid_t result = get_windows_debug_event (pid, ourstatus, options);

- if (result != null_ptid)
+ if ((options & TARGET_WNOHANG) != 0
+ && ourstatus->kind () == TARGET_WAITKIND_IGNORE)
+ return result;
+
+ if (ourstatus->kind () == TARGET_WAITKIND_SPURIOUS)
+ {
+ CHECK (windows_continue (DBG_CONTINUE,
+ windows_process.desired_stop_thread_id, 0));
+ }
+ else if (ourstatus->kind () != TARGET_WAITKIND_IGNORE)
{
if (ourstatus->kind () != TARGET_WAITKIND_EXITED
- && ourstatus->kind () != TARGET_WAITKIND_SIGNALLED)
+ && ourstatus->kind () != TARGET_WAITKIND_SIGNALLED)
{
windows_thread_info *th = windows_process.find_thread (result);

- if (th != nullptr)
+ th->stopped_at_software_breakpoint = false;
+ if (windows_process.current_event.dwDebugEventCode
+ == EXCEPTION_DEBUG_EVENT
+ && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
+ == EXCEPTION_BREAKPOINT)
+ || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
+ == STATUS_WX86_BREAKPOINT))
+ && windows_process.windows_initialization_done)
{
- th->stopped_at_software_breakpoint = false;
- if (windows_process.current_event.dwDebugEventCode
- == EXCEPTION_DEBUG_EVENT
- && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
- == EXCEPTION_BREAKPOINT)
- || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
- == STATUS_WX86_BREAKPOINT))
- && windows_process.windows_initialization_done)
- {
- th->stopped_at_software_breakpoint = true;
- th->pc_adjusted = false;
- }
+ th->stopped_at_software_breakpoint = true;
+ th->pc_adjusted = false;
}
}

--
2.49.0