Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] [gdb/tdep] Don't call WaitForSingleObject with INFINITE arg
@ 2025-06-05 15:03 Tom de Vries
  2025-06-05 16:15 ` Pedro Alves
  0 siblings, 1 reply; 12+ messages in thread
From: Tom de Vries @ 2025-06-05 15:03 UTC (permalink / raw)
  To: gdb-patches

I decided to try to build and test gdb on Windows.

I found a page on the wiki ( https://sourceware.org/gdb/wiki/BuildingOnWindows
) suggesting three ways of building gdb:
- MinGW,
- MinGW on Cygwin, and
- Cygwin.

I picked Cygwin, because I've used it before (though not recently).

I managed to install Cygwin and sufficient packages to build gdb and start the
testsuite.

However, testsuite progress ground to a halt at gdb.base/branch-to-self.exp.
[ AFAICT, similar problems reported here [1]. ]

I managed to reproduce this hang by running just the test-case.

I attempted to kill the hanging processes by:
- first killing the inferior process, using the cygwin "kill -9" command, and
- then killing the gdb process, likewise.

But the gdb process remained, and I had to point-and-click my way through task
manager to actually kill the gdb process.

I investigated this by attaching to the hanging gdb process.  Looking at the
main thread, I saw it was stopped in a call to WaitForSingleObject, with
the dwMilliseconds parameter set to INFINITE.

The backtrace in more detail:
...
(gdb) bt
 #0  0x00007fff196fc044 in ntdll!ZwWaitForSingleObject () from
     /cygdrive/c/windows/SYSTEM32/ntdll.dll
 #1  0x00007fff16bbcdcf in WaitForSingleObjectEx () from
     /cygdrive/c/windows/System32/KERNELBASE.dll
 #2  0x0000000100998065 in wait_for_single (handle=0x1b8, howlong=4294967295) at
     gdb/windows-nat.c:435
 #3  0x0000000100999aa7 in
     windows_nat_target::do_synchronously(gdb::function_view<bool ()>)
       (this=this@entry=0xa001c6fe0, func=...) at gdb/windows-nat.c:487
 #4  0x000000010099a7fb in windows_nat_target::wait_for_debug_event_main_thread
     (event=<optimized out>, this=0xa001c6fe0)
     at gdb/../gdbsupport/function-view.h:296
 #5  windows_nat_target::kill (this=0xa001c6fe0) at gdb/windows-nat.c:2917
 #6  0x00000001008f2f86 in target_kill () at gdb/target.c:901
 #7  0x000000010091fc46 in kill_or_detach (from_tty=0, inf=0xa000577d0)
     at gdb/top.c:1658
 #8  quit_force (exit_arg=<optimized out>, from_tty=from_tty@entry=0)
     at gdb/top.c:1759
 #9  0x00000001004f9ea8 in quit_command (args=args@entry=0x0,
     from_tty=from_tty@entry=0) at gdb/cli/cli-cmds.c:483
 #10 0x000000010091c6d0 in quit_cover () at gdb/top.c:295
 #11 0x00000001005e3d8a in async_disconnect (arg=<optimized out>)
     at gdb/event-top.c:1496
 #12 0x0000000100499c45 in invoke_async_signal_handlers ()
     at gdb/async-event.c:233
 #13 0x0000000100eb23d6 in gdb_do_one_event (mstimeout=mstimeout@entry=-1)
     at gdbsupport/event-loop.cc:198
 #14 0x00000001006df94a in interp::do_one_event (mstimeout=-1,
     this=<optimized out>) at gdb/interps.h:87
 #15 start_event_loop () at gdb/main.c:402
 #16 captured_command_loop () at gdb/main.c:466
 #17 0x00000001006e2865 in captured_main (data=0x7ffffcba0) at gdb/main.c:1346
 #18 gdb_main (args=args@entry=0x7ffffcc10) at gdb/main.c:1365
 #19 0x0000000100f98c70 in main (argc=10, argv=0xa000129f0) at gdb/gdb.c:38
...

In the docs [2], I read that using an INFINITE argument to WaitForSingleObject
might cause a system deadlock.

This prompted me to try this simple change in wait_for_single:
...
   while (true)
     {
-      DWORD r = WaitForSingleObject (handle, howlong);
+      DWORD r = WaitForSingleObject (handle,
+                                     howlong == INFINITE ? 100 : howlong);
+      if (howlong == INFINITE && r == WAIT_TIMEOUT)
+        continue;
...
with the timeout of 0.1 second estimated to be:
- small enough for gdb to feel reactive, and
- big enough not to consume too much cpu cycles with looping.

And indeed, the test-case, while still failing, now finishes in ~50 seconds.

While there may be an underlying bug that triggers this behaviour, the failure
mode is so severe that I consider it a bug in itself.

Fix this by avoiding calling WaitForSingleObject with INFINITE argument.

Tested on x86_64-cygwin, by running the testsuite past the test-case.

PR tdep/32894
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32894

[1] https://sourceware.org/pipermail/gdb-patches/2025-May/217949.html
[2] https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
---
 gdb/windows-nat.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 461d9eb9af5..b1c49c9d891 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -432,7 +432,10 @@ wait_for_single (HANDLE handle, DWORD howlong)
 {
   while (true)
     {
-      DWORD r = WaitForSingleObject (handle, howlong);
+      DWORD milliseconds = howlong == INFINITE ? 100 : howlong;
+      DWORD r = WaitForSingleObject (handle, milliseconds);
+      if (howlong == INFINITE && r == WAIT_TIMEOUT)
+	continue;
       if (r == WAIT_OBJECT_0)
 	return;
       if (r == WAIT_FAILED)

base-commit: 96662aacaa0cf0a9766d874fc9577a5da417dbcc
-- 
2.43.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-06-10  9:52 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-05 15:03 [PATCH] [gdb/tdep] Don't call WaitForSingleObject with INFINITE arg Tom de Vries
2025-06-05 16:15 ` Pedro Alves
2025-06-05 16:25   ` Pedro Alves
2025-06-06  6:27     ` Tom de Vries
2025-06-06  7:12   ` Tom de Vries
2025-06-06 15:14     ` Pedro Alves
2025-06-06 15:27       ` Pedro Alves
2025-06-09 17:52         ` Pedro Alves
2025-06-10  7:13           ` Tom de Vries
2025-06-06 13:11   ` Pedro Alves
2025-06-10  7:13     ` Tom de Vries
2025-06-10  9:51       ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox