From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il1-x12a.google.com (mail-il1-x12a.google.com [IPv6:2607:f8b0:4864:20::12a]) by sourceware.org (Postfix) with ESMTPS id 2EA73385842B for ; Wed, 27 Apr 2022 17:28:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2EA73385842B Received: by mail-il1-x12a.google.com with SMTP id k12so418972ilv.3 for ; Wed, 27 Apr 2022 10:28:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4lTbfC8/wHM79KRmfH6dSxkKmN72e9YHxEm7/JYEMDg=; b=q0q3TFw0aCF3f8eqay4HEbMeINjs6gHl84cpCUkz9ZkFG1iB3P65CErhypIMMnolmy gh3MwVMP/hIFYAbHYzYg5geItgp7JZx1QQ0MeQxIFcELkbbV8hjlTHLoBixkxRhin3Vo cJYL/kXgcOusONz7+g0Jt5Fz21PX28/qOhitUY/9z26jTof5gAyOLXLbD4KLWM327xou FDurFMtapYPjzJTtxlVc3k4mtR3y2gVDorLnjviQGsvRBG/NGkq1XH9vBV3UV1gfvbd0 bDw057WNrkxIUM4XJTuhVOTw8rSh/eWubTeWWO6cOhk8oUaoxqhZ9Y58JPM+MAlga8mx EqWw== X-Gm-Message-State: AOAM530X1/JJ7kTyTmbNKK4faFr5N5jB58zmAHcCoebkJD18nttQ6AfB eJH8/l/1nEyMm/D4h280FFLMSSHJYRlLgA== X-Google-Smtp-Source: ABdhPJxsC7RYjskjC2hwle9WeRuPfRUfA2Xi3RlahugttdIfR2TZMxCX5HPX0dS7m/1TpjhBILCNKw== X-Received: by 2002:a92:c54a:0:b0:2cc:1b37:affa with SMTP id a10-20020a92c54a000000b002cc1b37affamr10955039ilj.323.1651080483305; Wed, 27 Apr 2022 10:28:03 -0700 (PDT) Received: from murgatroyd.Home (71-211-158-194.hlrn.qwest.net. [71.211.158.194]) by smtp.gmail.com with ESMTPSA id e17-20020a5d8ad1000000b00644d51bbffcsm12053539iot.36.2022.04.27.10.28.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Apr 2022 10:28:02 -0700 (PDT) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 2/2] Implement pid_to_exec_file for Windows in gdbserver Date: Wed, 27 Apr 2022 11:28:00 -0600 Message-Id: <20220427172800.858822-3-tromey@adacore.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220427172800.858822-1-tromey@adacore.com> References: <20220427172800.858822-1-tromey@adacore.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Apr 2022 17:28:06 -0000 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. --- 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//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 29fd0a3a69b..4244426f5eb 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -249,6 +249,8 @@ struct windows_process_info gdb::optional 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 @@ -267,6 +269,18 @@ struct windows_process_info 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//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 192ea465e69..ca9df030fd6 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -1516,6 +1516,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 @@ class win32_process_target : public process_stratum_target 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. */ -- 2.34.1