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).