Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH 0/3] Show CONTEXT_EXCEPTION_REQUEST info in "info threads"
Date: Mon,  4 May 2026 18:33:39 +0100	[thread overview]
Message-ID: <20260504173344.1278735-1-pedro@palves.net> (raw)

While looking at gdb.threads/hand-call-in-threads.exp failures on
Cygwin, I noticed that on Windows, if you do an infcall on a thread
that is currently blocked in a syscall (e.g., on
ntdll!ZwWaitForMultipleObjects), the infcall will hang (won't really
run) until the thread returns from the system call on its own.  On
Linux, most system calls are interruptible, so you won't see this
happening.  On Windows however, system calls are NOT interruptible.

If you pause the hung thread with Ctrl-C, you'll see that its (user
space) PC won't have changed, still pointing to the entry to the
function GDB wants to call.

For example (with a simple program that just calls sleep in the main
thread):

 ...
 (gdb) t 2
 [Switching to thread 2 (Thread 15648.0x3d58)]
 #0  0x00007ffde37057b4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
 (gdb) p malloc(0)
 * hang, press ctrl-c *
 [New Thread 15648.0x12d4 (id 8)]

 Thread 8 received signal SIGINT, Interrupt.
 [Switching to Thread 15648.0x12d4]
 0x00007ffde00aa464 in KERNELBASE!CtrlRoutine () from C:/WINDOWS/System32/KERNELBASE.dll
 ❌️ The program received a signal in another thread while
 making a function call from GDB.
 Evaluation of the expression containing the function
 (malloc(size_t)) will be abandoned.
 When the function is done executing, GDB will silently stop.
 (gdb) info threads
   Id   Target Id                                     Frame
   1    Thread 15648.0x4338 "sleeper"                 main () at sleeper.c:5
   2    Thread 15648.0x3d58                           malloc (size=0) at /usr/src/debug/cygwin-3.6.3-1/winsup/cygwin/mm/malloc_wrapper.cc:85
   3    Thread 15648.0x27e0 "sig"                     0x00007ffde3701bc4 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
   4    Thread 15648.0x26f0                           0x00007ffde37057b4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
   6    Thread 15648.0x49f0                           0x00007ffde37057b4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
   7    Thread 15648.0x23b0                           0x00007ffde37057b4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
 * 8    Thread 15648.0x12d4                           0x00007ffde00aa464 in KERNELBASE!CtrlRoutine () from C:/WINDOWS/System32/KERNELBASE.dll

Now, I remembered from reading about SuspendThread and
GetThreadContext woes early on while working in the non-stop support,
that there was a way to tell whether the interrupted thread was
running kernel or user space code.  After digging through my
bookmarks, I found it.  It's explained here, in a comment from 2014 on
a blog from 2010:

 https://zachsaw.blogspot.com/2010/11/wow64-bug-getthreadcontext-may-return.html#c5639760895973344002

Other places around the interwebs that I found with
CONTEXT_EXCEPTION_REQUEST references all pointed to that sole
comment...  Microsoft doesn't document these flags, AFAICT, other than
a brief mention here:
https://learn.microsoft.com/en-us/windows/win32/debug/working-with-xstate-context
Still, even Wine supports this, and MinGW headers define the
constants.

This series makes the Windows native target expose that information in
"info threads" extra info, like so:

 (gdb) info threads
   Id   Target Id                                     Frame
   1    Thread 15648.0x4338 "sleeper"                 main () at sleeper.c:5
   2    Thread 15648.0x3d58 (in syscall)              0x00007ffde37057b4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
   3    Thread 15648.0x27e0 "sig" (in syscall)        0x00007ffde3701bc4 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
   4    Thread 15648.0x26f0 (in syscall)              0x00007ffde37057b4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
 * 5    Thread 15648.0xff8 (in exception)             0x00007ffde00aa464 in KERNELBASE!CtrlRoutine () from C:/WINDOWS/System32/KERNELBASE.dll
 (gdb)

Above, we can see that thread 1 is running user space code, threads 2
to 4 are in some system call, and thread 5 raised an exception (a
Ctrl-C).

I could imagine us adding a warning whenever GDB changes register
contents or does an infcall on a thread blocked inside a syscall, or
something like that.  But for now, I'm happy with at least seeing the
info.

For gdb.threads/hand-call-in-threads.exp at least, the testcase runs
the infcall on the wrong thread, leading to the hang situation.  Many
testcases assume that threads 2 and above are the that that test
program spawns, which is incorrect on Windows -- the Cygwin runtime
and Windows spawn a few helper threads, so test program threads start
at 4 or 5.  The runtime threads are usually blocked inside a system
call, so doing an infcall on them will hang.

FWIW, I tried the same situation with Visual Studio, and it doesn't
prevent evaluating the expression -- a dialog pops up saying something
like "evaluating expression", and then after a few seconds it aborts
it.  We already support timing out of infcalls nowadays, except we
default to an infinite timeout, so we're mostly covered.

Pedro Alves (3):
  Windows gdb: Show CONTEXT_EXCEPTION_REQUEST info in "info threads"
  gdb manual: Cygwin => Windows
  Windows gdb: Document "info threads" Windows specifics

 gdb/doc/gdb.texinfo   | 67 ++++++++++++++++++++++++++++++-------------
 gdb/nat/windows-nat.h |  3 +-
 gdb/windows-nat.c     | 22 ++++++++++++++
 3 files changed, 71 insertions(+), 21 deletions(-)


base-commit: 8c0ac471835ec86a67c5b42713d9f138f31e4014
-- 
2.53.0


             reply	other threads:[~2026-05-04 17:34 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-04 17:33 Pedro Alves [this message]
2026-05-04 17:33 ` [PATCH 1/3] Windows gdb: " Pedro Alves
2026-05-04 19:12   ` Eli Zaretskii
2026-05-04 17:33 ` [PATCH 2/3] gdb manual: Cygwin => Windows Pedro Alves
2026-05-04 19:18   ` Eli Zaretskii
2026-05-07 17:42     ` Pedro Alves
2026-05-08 13:08       ` Eli Zaretskii
2026-05-04 17:33 ` [PATCH 3/3] Windows gdb: Document "info threads" Windows specifics Pedro Alves
2026-05-04 19:14   ` Eli Zaretskii
2026-05-07 17:59     ` Pedro Alves
2026-05-08 13:12       ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260504173344.1278735-1-pedro@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox