[2/5] Fix "set cwd ..." on Cygwin, part 2

Message ID 20260522001626.393908-3-pedro@palves.net
State New
Headers
Series Fix a few Cygwin/MinGW problems |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed

Commit Message

Pedro Alves May 22, 2026, 12:16 a.m. UTC
  Even after the previous patch, on both native and gdbserver Cygwin, we
get:

 (gdb) set cwd /cygdrive/d/cygwin-gdb/build-testsuite/outputs/gdb.base/exitsignal
 (gdb) start
 Temporary breakpoint 3 at 0x100401094: file /home/alves/rocm/gdb/src/gdb/testsuite/gdb.base/segv.c, line 26.
 Starting program: /cygdrive/d/cygwin-gdb/build-testsuite/outputs/gdb.base/exitsignal/exitsignal.exe
 ❌️ Error creating process /cygdrive/d/cygwin-gdb/build-testsuite/outputs/gdb.base/exitsignal/exitsignal.exe (error 6): The handle is invalid.
 (gdb)

On the native side, this is because in
windows_nat_target::create_inferior, we unconditionally convert
forward slashes to backward slashes:

  /cygdrive/d/cygwin-gdb/build-testsuite/outputs/gdb.base/exitsignal
  =>
  \cygdrive\d\cygwin-gdb\build-testsuite\outputs\gdb.base\exitsignal

and then cygwin_conv_path(CCP_POSIX_TO_WIN_W) does nothing on such
path, as the backward slashes make the path not look like a Unix-style
path.

CreateProcess then fails to CD into that directory, as that's not a
real Windows native path.

The fix is to not do the slashes replacement on Cygwin.

On the gdbserver side, we're just completely missing the
cygwin_conv_path logic.  This commit adds it.  The code isn't shared
with GDB because GDB uses wide chars, and gdbserver uses narrow char.

Change-Id: I004f2a562757a566423f6acb9aecfcc1a7f2f746
commit-id: 85aa8c22
---
 gdb/windows-nat.c      | 14 ++++++++------
 gdbserver/win32-low.cc | 30 +++++++++++++++++++++++++-----
 2 files changed, 33 insertions(+), 11 deletions(-)
  

Comments

Tom Tromey May 22, 2026, 2:37 p.m. UTC | #1
>>>>> "Pedro" == Pedro Alves <pedro@palves.net> writes:

Pedro> On the gdbserver side, we're just completely missing the
Pedro> cygwin_conv_path logic.  This commit adds it.  The code isn't shared
Pedro> with GDB because GDB uses wide chars, and gdbserver uses narrow char.

I wonder why, and whether this results in any differences in behavior.

Anyway this looks good.
Approved-By: Tom Tromey <tom@tromey.com>

Tom
  
Pedro Alves May 25, 2026, 4:43 p.m. UTC | #2
On 2026-05-22 15:37, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <pedro@palves.net> writes:
> 
> Pedro> On the gdbserver side, we're just completely missing the
> Pedro> cygwin_conv_path logic.  This commit adds it.  The code isn't shared
> Pedro> with GDB because GDB uses wide chars, and gdbserver uses narrow char.
> 
> I wonder why, and whether this results in any differences in behavior.
> 

For the "why", I think it's just historical.

See:

 https://inbox.sourceware.org/gdb-patches/20100228150844.GH5683@calimero.vinschen.de/

... for when GDB started using the Wide versions, which talks about the Ansi limitations.

And then, nobody ever adjusted GDBserver.

> Anyway this looks good.
> Approved-By: Tom Tromey <tom@tromey.com>

Thanks, I merged patches 1, 2, and 3.  I'll be sending a v2 with a new version of the remainder, in a sec.

Pedro Alves
  

Patch

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 862568fa21e..a284438bd36 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -2881,10 +2881,17 @@  windows_nat_target::create_inferior (const char *exec_file,
   else
     {
       expanded_infcwd = gdb_tilde_expand (inferior_cwd);
+      inferior_cwd = expanded_infcwd.c_str ();
+#ifndef __CYGWIN__
       /* Mirror slashes on inferior's cwd.  */
       std::replace (expanded_infcwd.begin (), expanded_infcwd.end (),
 		    '/', '\\');
-      inferior_cwd = expanded_infcwd.c_str ();
+#else
+      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W,
+			    inferior_cwd,
+			    infcwd, sizeof (infcwd)) < 0)
+	error (_("Error converting inferior cwd: %d"), errno);
+#endif
     }
 
   memset (&si, 0, sizeof (si));
@@ -2923,11 +2930,6 @@  windows_nat_target::create_inferior (const char *exec_file,
       flags |= DEBUG_PROCESS;
     }
 
-  if (inferior_cwd != NULL
-      && cygwin_conv_path (CCP_POSIX_TO_WIN_W, inferior_cwd,
-			   infcwd, sizeof (infcwd)) < 0)
-    error (_("Error converting inferior cwd: %d"), errno);
-
   args = (wchar_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
 			     * sizeof (wchar_t));
   wcscpy (args, toexec);
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 469ff32f070..6f1cf5ed025 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -448,9 +448,11 @@  static BOOL
 create_process (const char *program, char *args,
 		DWORD flags, PROCESS_INFORMATION *pi)
 {
-  const std::string &inferior_cwd = get_inferior_cwd ();
   BOOL ret;
   size_t argslen, proglen;
+#ifdef __CYGWIN__
+  char infcwd_buf[PATH_MAX];
+#endif
 
   proglen = strlen (program) + 1;
   argslen = strlen (args) + proglen;
@@ -458,6 +460,27 @@  create_process (const char *program, char *args,
   STARTUPINFOA si = { sizeof (STARTUPINFOA) };
   char *program_and_args = (char *) alloca (argslen + 1);
 
+  const char *inferior_cwd = get_inferior_cwd ().c_str ();
+  std::string expanded_infcwd;
+  if (*inferior_cwd == '\0')
+    inferior_cwd = nullptr;
+  else
+    {
+      expanded_infcwd = gdb_tilde_expand (inferior_cwd);
+      inferior_cwd = expanded_infcwd.c_str ();
+#ifndef __CYGWIN__
+      /* Mirror slashes on inferior's cwd.  */
+      std::replace (expanded_infcwd.begin (), expanded_infcwd.end (),
+		    '/', '\\');
+#else
+      if (cygwin_conv_path (CCP_POSIX_TO_WIN_A,
+			    inferior_cwd,
+			    infcwd_buf, sizeof (infcwd_buf)) < 0)
+	error (_("Error converting inferior cwd: %d"), errno);
+      inferior_cwd = infcwd_buf;
+#endif
+    }
+
   strcpy (program_and_args, program);
   strcat (program_and_args, " ");
   strcat (program_and_args, args);
@@ -465,10 +488,7 @@  create_process (const char *program, char *args,
 			program_and_args,  /* command line */
 			flags,             /* start flags */
 			NULL,              /* environment */
-			/* current directory */
-			(inferior_cwd.empty ()
-			 ? NULL
-			 : gdb_tilde_expand (inferior_cwd).c_str()),
+			inferior_cwd,      /* current directory */
 			get_client_state ().disable_randomization,
 			&si,               /* start info */
 			pi);               /* proc info */