public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Implement pid_to_exec_file for Windows in gdbserver
@ 2022-05-13 14:37 Tom Tromey
  0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2022-05-13 14:37 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fcab58390fc7a972f499b8ae1b2ff06994b6c1fc

commit fcab58390fc7a972f499b8ae1b2ff06994b6c1fc
Author: Tom Tromey <tromey@adacore.com>
Date:   Tue Apr 26 14:16:57 2022 -0600

    Implement pid_to_exec_file for Windows in gdbserver
    
    I noticed that gdbserver did not implement pid_to_exec_file for
    Windows, while gdb did implement it.  This patch moves the code to
    nat/windows-nat.c, so that it can be shared.  This makes the gdbserver
    implementation trivial.

Diff:
---
 gdb/nat/windows-nat.c  | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/nat/windows-nat.h  | 14 ++++++++
 gdb/windows-nat.c      | 88 +----------------------------------------------
 gdbserver/win32-low.cc |  6 ++++
 gdbserver/win32-low.h  |  5 +++
 5 files changed, 119 insertions(+), 87 deletions(-)

diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index c8db19439f3..71a18a0efa9 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -144,6 +144,99 @@ windows_thread_info::thread_name ()
   return name.get ();
 }
 
+/* Try to determine the executable filename.
+
+   EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
+
+   Upon success, the filename is stored inside EXE_NAME_RET, and
+   this function returns nonzero.
+
+   Otherwise, this function returns zero and the contents of
+   EXE_NAME_RET is undefined.  */
+
+int
+windows_process_info::get_exec_module_filename (char *exe_name_ret,
+						size_t exe_name_max_len)
+{
+  DWORD len;
+  HMODULE dh_buf;
+  DWORD cbNeeded;
+
+  cbNeeded = 0;
+#ifdef __x86_64__
+  if (wow64_process)
+    {
+      if (!EnumProcessModulesEx (handle,
+				 &dh_buf, sizeof (HMODULE), &cbNeeded,
+				 LIST_MODULES_32BIT)
+	  || !cbNeeded)
+	return 0;
+    }
+  else
+#endif
+    {
+      if (!EnumProcessModules (handle,
+			       &dh_buf, sizeof (HMODULE), &cbNeeded)
+	  || !cbNeeded)
+	return 0;
+    }
+
+  /* We know the executable is always first in the list of modules,
+     which we just fetched.  So no need to fetch more.  */
+
+#ifdef __CYGWIN__
+  {
+    /* Cygwin prefers that the path be in /x/y/z format, so extract
+       the filename into a temporary buffer first, and then convert it
+       to POSIX format into the destination buffer.  */
+    cygwin_buf_t *pathbuf = (cygwin_buf_t *) alloca (exe_name_max_len * sizeof (cygwin_buf_t));
+
+    len = GetModuleFileNameEx (current_process_handle,
+			       dh_buf, pathbuf, exe_name_max_len);
+    if (len == 0)
+      error (_("Error getting executable filename: %u."),
+	     (unsigned) GetLastError ());
+    if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, exe_name_ret,
+			  exe_name_max_len) < 0)
+      error (_("Error converting executable filename to POSIX: %d."), errno);
+  }
+#else
+  len = GetModuleFileNameEx (handle,
+			     dh_buf, exe_name_ret, exe_name_max_len);
+  if (len == 0)
+    error (_("Error getting executable filename: %u."),
+	   (unsigned) GetLastError ());
+#endif
+
+    return 1;	/* success */
+}
+
+const char *
+windows_process_info::pid_to_exec_file (int pid)
+{
+  static char path[MAX_PATH];
+#ifdef __CYGWIN__
+  /* Try to find exe name as symlink target of /proc/<pid>/exe.  */
+  int nchars;
+  char procexe[sizeof ("/proc/4294967295/exe")];
+
+  xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid);
+  nchars = readlink (procexe, path, sizeof(path));
+  if (nchars > 0 && nchars < sizeof (path))
+    {
+      path[nchars] = '\0';	/* Got it */
+      return path;
+    }
+#endif
+
+  /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
+     of gdb, or we're trying to debug a non-Cygwin windows executable.  */
+  if (!get_exec_module_filename (path, sizeof (path)))
+    path[0] = '\0';
+
+  return path;
+}
+
 /* Return the name of the DLL referenced by H at ADDRESS.  UNICODE
    determines what sort of string is read from the inferior.  Returns
    the name of the DLL, or NULL on error.  If a name is returned, it
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 9f7f8b63192..450ba69c844 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -248,6 +248,8 @@ struct windows_process_info
 
   gdb::optional<pending_stop> fetch_pending_stop (bool debug_events);
 
+  const char *pid_to_exec_file (int);
+
 private:
 
   /* Handle MS_VC_EXCEPTION when processing a stop.  MS_VC_EXCEPTION is
@@ -266,6 +268,18 @@ private:
      presumed loaded.  */
 
   void add_dll (LPVOID load_addr);
+
+  /* Try to determine the executable filename.
+
+     EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
+
+     Upon success, the filename is stored inside EXE_NAME_RET, and
+     this function returns nonzero.
+
+     Otherwise, this function returns zero and the contents of
+     EXE_NAME_RET is undefined.  */
+
+  int get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len);
 };
 
 /* A simple wrapper for ContinueDebugEvent that continues the last
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index cd43409a02f..11f54302b11 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1937,98 +1937,12 @@ windows_nat_target::detach (inferior *inf, int from_tty)
   maybe_unpush_target ();
 }
 
-/* Try to determine the executable filename.
-
-   EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
-
-   Upon success, the filename is stored inside EXE_NAME_RET, and
-   this function returns nonzero.
-
-   Otherwise, this function returns zero and the contents of
-   EXE_NAME_RET is undefined.  */
-
-static int
-windows_get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len)
-{
-  DWORD len;
-  HMODULE dh_buf;
-  DWORD cbNeeded;
-
-  cbNeeded = 0;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    {
-      if (!EnumProcessModulesEx (windows_process.handle,
-				 &dh_buf, sizeof (HMODULE), &cbNeeded,
-				 LIST_MODULES_32BIT)
-	  || !cbNeeded)
-	return 0;
-    }
-  else
-#endif
-    {
-      if (!EnumProcessModules (windows_process.handle,
-			       &dh_buf, sizeof (HMODULE), &cbNeeded)
-	  || !cbNeeded)
-	return 0;
-    }
-
-  /* We know the executable is always first in the list of modules,
-     which we just fetched.  So no need to fetch more.  */
-
-#ifdef __CYGWIN__
-  {
-    /* Cygwin prefers that the path be in /x/y/z format, so extract
-       the filename into a temporary buffer first, and then convert it
-       to POSIX format into the destination buffer.  */
-    cygwin_buf_t *pathbuf = (cygwin_buf_t *) alloca (exe_name_max_len * sizeof (cygwin_buf_t));
-
-    len = GetModuleFileNameEx (current_process_handle,
-			       dh_buf, pathbuf, exe_name_max_len);
-    if (len == 0)
-      error (_("Error getting executable filename: %u."),
-	     (unsigned) GetLastError ());
-    if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, exe_name_ret,
-			  exe_name_max_len) < 0)
-      error (_("Error converting executable filename to POSIX: %d."), errno);
-  }
-#else
-  len = GetModuleFileNameEx (windows_process.handle,
-			     dh_buf, exe_name_ret, exe_name_max_len);
-  if (len == 0)
-    error (_("Error getting executable filename: %u."),
-	   (unsigned) GetLastError ());
-#endif
-
-    return 1;	/* success */
-}
-
 /* The pid_to_exec_file target_ops method for this platform.  */
 
 const char *
 windows_nat_target::pid_to_exec_file (int pid)
 {
-  static char path[__PMAX];
-#ifdef __CYGWIN__
-  /* Try to find exe name as symlink target of /proc/<pid>/exe.  */
-  int nchars;
-  char procexe[sizeof ("/proc/4294967295/exe")];
-
-  xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid);
-  nchars = readlink (procexe, path, sizeof(path));
-  if (nchars > 0 && nchars < sizeof (path))
-    {
-      path[nchars] = '\0';	/* Got it */
-      return path;
-    }
-#endif
-
-  /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
-     of gdb, or we're trying to debug a non-Cygwin windows executable.  */
-  if (!windows_get_exec_module_filename (path, sizeof (path)))
-    path[0] = '\0';
-
-  return path;
+  return windows_process.pid_to_exec_file (pid);
 }
 
 /* Print status information about what we're accessing.  */
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 5b91ab768e5..f941e8d2903 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -1515,6 +1515,12 @@ win32_process_target::thread_name (ptid_t thread)
   return th->thread_name ();
 }
 
+const char *
+win32_process_target::pid_to_exec_file (int pid)
+{
+  return windows_process.pid_to_exec_file (pid);
+}
+
 /* The win32 target ops object.  */
 
 static win32_process_target the_win32_target;
diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h
index c5f40dd8d0a..d16f1f9609c 100644
--- a/gdbserver/win32-low.h
+++ b/gdbserver/win32-low.h
@@ -160,6 +160,11 @@ public:
   bool supports_stopped_by_sw_breakpoint () override;
 
   const char *thread_name (ptid_t thread) override;
+
+  bool supports_pid_to_exec_file () override
+  { return true; }
+
+  const char *pid_to_exec_file (int pid) override;
 };
 
 /* The sole Windows process.  */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-13 14:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-13 14:37 [binutils-gdb] Implement pid_to_exec_file for Windows in gdbserver Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).