[newlib-cygwin/cygwin-3_6-branch] Cygwin: pty: Fix nat_pipe_owner_pid when gdb runs non-cygwin app

Takashi Yano via Cygwin-cvs <[email protected]> Thu, 9 Jul 2026 12:31:55 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dfb1d831e6c0=
6606c3a36565ef28e7388f63c38cf

commit fb1d831e6c06606c3a36565ef28e7388f63c38cf
Author: Takashi Yano <[email protected]>
Date:   Wed Jul 8 21:54:45 2026 +0900

    Cygwin: pty: Fix nat_pipe_owner_pid when gdb runs non-cygwin app
   =20
    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.
   =20
    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. exec_dwProcessId is
    the PID of the stub process, and dwProcessId is the PID of the spawned
    process in the stub process. However, when the caller is gdb, since
    the owner should be gdb itself, nat_pipe_owner_pid must be set to
    myself->dwProcessId where the normal process's PID is stored.
   =20
    With this fix, attach_console_temporarily() can be called with target
    pid equal to the process's own pid in gdb, in which case the attach
    operation is skipped.
   =20
    Note that this issue commonly occurs in programs that launch non-
    cygwin app directly via CreateProcess(), as gdb does.
   =20
    Fixes: 1e6c51d74136 ("Cygwin: pty: Reorganize the code path of setting =
up and closing pcon.")
    Signed-off-by: Takashi Yano <[email protected]>
    Reviewed-by: Johannes Schindelin <[email protected]>
    (cherry picked from commit 50f4ff48727f138bded3f1c4e41357b46df1ef95)

Diff:
---
 winsup/cygwin/fhandler/pty.cc | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 387bc03f3..c5081bcaf 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -3689,7 +3689,8 @@ skip_create:
   replace_nat_handles (hpConIn, hpConOut);
=20
   if (!process_alive (get_ttyp ()->nat_pipe_owner_pid))
-    get_ttyp ()->nat_pipe_owner_pid =3D myself->exec_dwProcessId;
+    get_ttyp ()->nat_pipe_owner_pid =3D
+      myself->exec_dwProcessId ? : myself->dwProcessId;
=20
   if (hpcon && nat_pipe_owner_self (get_ttyp ()->nat_pipe_owner_pid))
     {
@@ -4397,7 +4398,12 @@ fhandler_pty_slave::setup_for_non_cygwin_app (bool n=
opcon,
       fhandler_pty_slave *ptys =3D (fhandler_pty_slave *) fh;
       ptys->get_ttyp ()->switch_to_nat_pipe =3D true;
       if (!process_alive (ptys->get_ttyp ()->nat_pipe_owner_pid))
-	ptys->get_ttyp ()->nat_pipe_owner_pid =3D myself->exec_dwProcessId;
+	/* In normal case where the current process is the stub process for
+	   non-cygwin app, set owner to exec_dwProcessId (which is the PID
+	   of the stub process itself). In gdb case, since gdb itself
+	   should be the owner, the owner pid must be set to dwProcessId. */
+	ptys->get_ttyp ()->nat_pipe_owner_pid =3D
+	  myself->exec_dwProcessId ? : myself->dwProcessId;
     }
   bool pcon_enabled =3D false;
   if (!nopcon)
@@ -4525,6 +4531,8 @@ fhandler_pty_common::attach_console_temporarily (DWOR=
D target_pid)
 {
   DWORD resume_pid =3D 0;
   acquire_attach_mutex (mutex_timeout);
+  if (target_pid =3D=3D GetCurrentProcessId ())
+    return target_pid;
   pinfo pinfo_resume (myself->ppid);
   if (pinfo_resume)
     resume_pid =3D pinfo_resume->dwProcessId;
@@ -4543,6 +4551,11 @@ fhandler_pty_common::attach_console_temporarily (DWO=
RD target_pid)
 void
 fhandler_pty_common::resume_from_temporarily_attach (DWORD resume_pid)
 {
+  if (resume_pid =3D=3D GetCurrentProcessId ())
+    {
+      release_attach_mutex ();
+      return;
+    }
   bool console_exists =3D (resume_pid !=3D (DWORD) -1);
   if (!console_exists || resume_pid)
     {