[PATCH v2] Cygwin: pty: Fix nat_pipe_owner_pid when gdb runs non-cygwin app

Takashi Yano <[email protected]> Wed, 8 Jul 2026 23:30:06 +0900
Newsgroups gmane.os.cygwin.patches
Message-ID <[email protected]>
Previously, nat_pipe_owner_pid was incorrectly set to 0 when the
inferior of gdb was a non-cygwin app. Due to this bug, repeatedly
running a non-cygwin app under gdb could lead to an unexpected crash.

This occurred because the previous code in setup_for_non_cygwin_app()
set nat_pipe_owner_pid to exec_dwProcessId, which is correct when the
caller is the stub process of the non-cygwin app. However, when the
caller is gdb, the owner should be gdb itself, so nat_pipe_owner_pid
must be set to myself->dwProcessId.

With this fix, attach_console_temporarily() can be called with target
pid equal to the process's own pid, in which case the attach operation
is skipped.

Fixes: 1e6c51d74136 ("Cygwin: pty: Reorganize the code path of setting up and closing pcon.")
Signed-off-by: Takashi Yano <[email protected]>
Reviewed-by:
---
v2: Skip attaching operation when attaching to myself is requested.

 winsup/cygwin/fhandler/pty.cc | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 1b453a499..6ef4fa506 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -4734,7 +4734,11 @@ fhandler_pty_slave::setup_for_non_cygwin_app (bool nopcon,
       fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
       ptys->get_ttyp ()->switch_to_nat_pipe = true;
       if (!process_alive (ptys->get_ttyp ()->nat_pipe_owner_pid))
-	ptys->get_ttyp ()->nat_pipe_owner_pid = myself->exec_dwProcessId;
+	/* In normal case where the current process is the stub process for
+	   non-cygwin app, set owner to exec_dwProcessId (non-cygwin app).
+	   However, in gdb case, gdb itself should be the owner. */
+	ptys->get_ttyp ()->nat_pipe_owner_pid =
+	  myself->exec_dwProcessId ? : myself->dwProcessId;
     }
   bool pcon_enabled = false;
   if (!nopcon)
@@ -4862,6 +4866,8 @@ fhandler_pty_common::attach_console_temporarily (DWORD target_pid)
 {
   DWORD resume_pid = 0;
   acquire_attach_mutex (mutex_timeout);
+  if (target_pid == GetCurrentProcessId ())
+    return target_pid;
   pinfo pinfo_resume (myself->ppid);
   if (pinfo_resume)
     resume_pid = pinfo_resume->dwProcessId;
@@ -4880,6 +4886,11 @@ fhandler_pty_common::attach_console_temporarily (DWORD target_pid)
 void
 fhandler_pty_common::resume_from_temporarily_attach (DWORD resume_pid)
 {
+  if (resume_pid == GetCurrentProcessId ())
+    {
+      release_attach_mutex ();
+      return;
+    }
   bool console_exists = (resume_pid != (DWORD) -1);
   if (!console_exists || resume_pid)
     {
-- 
2.51.0