From patchwork Fri Jan 20 10:54:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= X-Patchwork-Id: 1729474 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NyxGB1LPsz23fT for ; Fri, 20 Jan 2023 21:54:42 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5DA0938543AB for ; Fri, 20 Jan 2023 10:54:34 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.hazardy.de (mail.hazardy.de [78.94.181.132]) by sourceware.org (Postfix) with ESMTPS id 421EF3858C52; Fri, 20 Jan 2023 10:54:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 421EF3858C52 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hazardy.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hazardy.de Received: from NB-372.intranet.mimot.com (188-136-75-197-ftth-senden-dyn.heliweb.de [188.136.75.197]) by mail.hazardy.de (Postfix) with ESMTPSA id D4A22700276; Fri, 20 Jan 2023 11:54:13 +0100 (CET) From: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= To: gcc-patches@gcc.gnu.org, gcc@gcc.gnu.org Subject: [PATCH 1/4] libbacktrace: change all pc related variables to uintptr_t Date: Fri, 20 Jan 2023 11:54:06 +0100 Message-Id: <20230120105409.54949-1-gcc@hazardy.de> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" From: Björn Schäpers It's the right thing to do, since the PC shouldn't go out of the uintptr_t domain, and in backtrace_pcinfo the pc is uintptr_t. This is a preparation for a following patch. Tested on x86_64-linux and i686-w64-mingw32. -- >8 -- * dwarf.c: changed variables holding pc values from uint64_t to uintptr_t. Signed-off-by: Björn Schäpers --- libbacktrace/dwarf.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index 45cc9e77e40..0707ccddd3e 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -274,8 +274,8 @@ struct function struct function_addrs { /* Range is LOW <= PC < HIGH. */ - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; /* Function for this address range. */ struct function *function; }; @@ -356,8 +356,8 @@ struct unit struct unit_addrs { /* Range is LOW <= PC < HIGH. */ - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; /* Compilation unit for this address range. */ struct unit *u; }; @@ -1094,7 +1094,7 @@ resolve_addr_index (const struct dwarf_sections *dwarf_sections, uint64_t addr_base, int addrsize, int is_bigendian, uint64_t addr_index, backtrace_error_callback error_callback, void *data, - uint64_t *address) + uintptr_t *address) { uint64_t offset; struct dwarf_buf addr_buf; @@ -1194,7 +1194,7 @@ function_addrs_search (const void *vkey, const void *ventry) static int add_unit_addr (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *pvec) { @@ -1530,10 +1530,10 @@ lookup_abbrev (struct abbrevs *abbrevs, uint64_t code, lowpc/highpc is set or ranges is set. */ struct pcrange { - uint64_t lowpc; /* The low PC value. */ + uintptr_t lowpc; /* The low PC value. */ int have_lowpc; /* Whether a low PC value was found. */ int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */ - uint64_t highpc; /* The high PC value. */ + uintptr_t highpc; /* The high PC value. */ int have_highpc; /* Whether a high PC value was found. */ int highpc_is_relative; /* Whether highpc is relative to lowpc. */ int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */ @@ -1613,16 +1613,16 @@ add_low_high_range (struct backtrace_state *state, uintptr_t base_address, int is_bigendian, struct unit *u, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, - void *rdata, uint64_t lowpc, - uint64_t highpc, + void *rdata, uintptr_t lowpc, + uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, backtrace_error_callback error_callback, void *data, void *vec) { - uint64_t lowpc; - uint64_t highpc; + uintptr_t lowpc; + uintptr_t highpc; lowpc = pcrange->lowpc; if (pcrange->lowpc_is_addr_index) @@ -1663,7 +1663,7 @@ add_ranges_from_ranges ( struct unit *u, uint64_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, @@ -1727,10 +1727,10 @@ add_ranges_from_rnglists ( struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, uintptr_t base_address, int is_bigendian, - struct unit *u, uint64_t base, + struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, @@ -1796,8 +1796,8 @@ add_ranges_from_rnglists ( case DW_RLE_startx_endx: { uint64_t index; - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; index = read_uleb128 (&rnglists_buf); if (!resolve_addr_index (dwarf_sections, u->addr_base, @@ -1819,8 +1819,8 @@ add_ranges_from_rnglists ( case DW_RLE_startx_length: { uint64_t index; - uint64_t low; - uint64_t length; + uintptr_t low; + uintptr_t length; index = read_uleb128 (&rnglists_buf); if (!resolve_addr_index (dwarf_sections, u->addr_base, @@ -1905,7 +1905,7 @@ add_ranges (struct backtrace_state *state, uintptr_t base_address, int is_bigendian, struct unit *u, uint64_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, @@ -3183,7 +3183,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u, static int add_function_range (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *pvec) { @@ -3223,7 +3223,7 @@ add_function_range (struct backtrace_state *state, void *rdata, static int read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, - struct unit *u, uint64_t base, struct dwarf_buf *unit_buf, + struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf, const struct line_header *lhdr, backtrace_error_callback error_callback, void *data, struct function_vector *vec_function, From patchwork Fri Jan 20 10:54:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= X-Patchwork-Id: 1729475 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NyxHv0CVNz23gL for ; Fri, 20 Jan 2023 21:56:11 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 690F0394D89F for ; Fri, 20 Jan 2023 10:56:04 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.hazardy.de (mail.hazardy.de [78.94.181.132]) by sourceware.org (Postfix) with ESMTPS id 2DF8A3858C53; Fri, 20 Jan 2023 10:54:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2DF8A3858C53 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hazardy.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hazardy.de Received: from NB-372.intranet.mimot.com (188-136-75-197-ftth-senden-dyn.heliweb.de [188.136.75.197]) by mail.hazardy.de (Postfix) with ESMTPSA id 2104B700276; Fri, 20 Jan 2023 11:54:18 +0100 (CET) From: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= To: gcc-patches@gcc.gnu.org, gcc@gcc.gnu.org Subject: [PATCH 2/4] libbacktrace: detect executable path on windows Date: Fri, 20 Jan 2023 11:54:07 +0100 Message-Id: <20230120105409.54949-2-gcc@hazardy.de> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230120105409.54949-1-gcc@hazardy.de> References: <20230120105409.54949-1-gcc@hazardy.de> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" From: Björn Schäpers This is actually needed so that libstdc++'s implementation to be able to work on windows. Tested on x86_64-linux and i686-w64-mingw32. -- >8 -- * configure.ac: Add a check for windows.h. * configure, config.h.in: Regenerate. * fileline.c: Add windows_get_executable_path. * fileline.c (fileline_initialiez): Add a pass using windows_get_executable_path. Signed-off-by: Björn Schäpers Signed-off-by: Björn Schäpers --- libbacktrace/config.h.in | 3 +++ libbacktrace/configure | 13 ++++++++++++ libbacktrace/configure.ac | 2 ++ libbacktrace/fileline.c | 43 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in index a21e2eaf525..355e820741b 100644 --- a/libbacktrace/config.h.in +++ b/libbacktrace/config.h.in @@ -100,6 +100,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + /* Define if -lz is available. */ #undef HAVE_ZLIB diff --git a/libbacktrace/configure b/libbacktrace/configure index a5bd133f4e4..ef677423733 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -13403,6 +13403,19 @@ $as_echo "#define HAVE_LOADQUERY 1" >>confdefs.h fi +for ac_header in windows.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" +if test "x$ac_cv_header_windows_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINDOWS_H 1 +_ACEOF + +fi + +done + + # Check for the fcntl function. if test -n "${with_target_subdir}"; then case "${host}" in diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 1daaa2f62d2..b5feb29bcdc 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -377,6 +377,8 @@ if test "$have_loadquery" = "yes"; then AC_DEFINE(HAVE_LOADQUERY, 1, [Define if AIX loadquery is available.]) fi +AC_CHECK_HEADERS(windows.h) + # Check for the fcntl function. if test -n "${with_target_subdir}"; then case "${host}" in diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c index a40cd498114..73c2c8e8bc9 100644 --- a/libbacktrace/fileline.c +++ b/libbacktrace/fileline.c @@ -47,6 +47,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #include #endif +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_MEAN_AND_LEAN +#define WIN32_MEAN_AND_LEAN +#endif + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include +#endif + #include "backtrace.h" #include "internal.h" @@ -155,6 +167,28 @@ macho_get_executable_path (struct backtrace_state *state, #endif /* !defined (HAVE_MACH_O_DYLD_H) */ +#ifdef HAVE_WINDOWS_H + +static char * +windows_get_executable_path (char *buf, backtrace_error_callback error_callback, + void *data) +{ + if (GetModuleFileNameA (NULL, buf, MAX_PATH - 1) == 0) + { + error_callback (data, + "could not get the filename of the current executable", + (int) GetLastError ()); + return NULL; + } + return buf; +} + +#else /* !defined (HAVE_WINDOWS_H) */ + +#define windows_get_executable_path(buf, error_callback, data) NULL + +#endif /* !defined (HAVE_WINDOWS_H) */ + /* Initialize the fileline information from the executable. Returns 1 on success, 0 on failure. */ @@ -168,7 +202,11 @@ fileline_initialize (struct backtrace_state *state, int called_error_callback; int descriptor; const char *filename; +#ifdef HAVE_WINDOWS_H + char buf[MAX_PATH]; +#else char buf[64]; +#endif if (!state->threaded) failed = state->fileline_initialization_failed; @@ -192,7 +230,7 @@ fileline_initialize (struct backtrace_state *state, descriptor = -1; called_error_callback = 0; - for (pass = 0; pass < 8; ++pass) + for (pass = 0; pass < 9; ++pass) { int does_not_exist; @@ -224,6 +262,9 @@ fileline_initialize (struct backtrace_state *state, case 7: filename = macho_get_executable_path (state, error_callback, data); break; + case 8: + filename = windows_get_executable_path (buf, error_callback, data); + break; default: abort (); } From patchwork Fri Jan 20 10:54:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= X-Patchwork-Id: 1729473 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NyxG80Jj9z23fT for ; Fri, 20 Jan 2023 21:54:39 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 106193854392 for ; Fri, 20 Jan 2023 10:54:36 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.hazardy.de (mail.hazardy.de [78.94.181.132]) by sourceware.org (Postfix) with ESMTPS id 769053858C62; Fri, 20 Jan 2023 10:54:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 769053858C62 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hazardy.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hazardy.de Received: from NB-372.intranet.mimot.com (188-136-75-197-ftth-senden-dyn.heliweb.de [188.136.75.197]) by mail.hazardy.de (Postfix) with ESMTPSA id 5D7D67004A0; Fri, 20 Jan 2023 11:54:18 +0100 (CET) From: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= To: gcc-patches@gcc.gnu.org, gcc@gcc.gnu.org Subject: [PATCH 3/4] libbacktrace: work with aslr on windows Date: Fri, 20 Jan 2023 11:54:08 +0100 Message-Id: <20230120105409.54949-3-gcc@hazardy.de> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230120105409.54949-1-gcc@hazardy.de> References: <20230120105409.54949-1-gcc@hazardy.de> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" From: Björn Schäpers Any underflow which might happen, will be countered by an overflow in dwarf.c. Tested on x86_64-linux and i686-w64-mingw32. -- >8 -- Fixes https://github.com/ianlancetaylor/libbacktrace/issues/89 and https://github.com/ianlancetaylor/libbacktrace/issues/82. * pecoff.c (coff_add): Set the base_address of the module, to find the debug information on moved applications. Signed-off-by: Björn Schäpers Signed-off-by: Björn Schäpers --- libbacktrace/pecoff.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c index 87b3c0cc647..296f1357b5f 100644 --- a/libbacktrace/pecoff.c +++ b/libbacktrace/pecoff.c @@ -39,6 +39,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "backtrace.h" #include "internal.h" +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_MEAN_AND_LEAN +#define WIN32_MEAN_AND_LEAN +#endif + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include +#endif + /* Coff file header. */ typedef struct { @@ -610,6 +622,8 @@ coff_add (struct backtrace_state *state, int descriptor, int debug_view_valid; int is_64; uintptr_t image_base; + uintptr_t base_address = 0; + uintptr_t module_handle; struct dwarf_sections dwarf_sections; *found_sym = 0; @@ -856,7 +870,12 @@ coff_add (struct backtrace_state *state, int descriptor, + (sections[i].offset - min_offset)); } - if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections, +#ifdef HAVE_WINDOWS_H + module_handle = (uintptr_t) GetModuleHandleW (NULL); + base_address = module_handle - image_base; +#endif + + if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, 0, /* FIXME: is_bigendian */ NULL, /* altlink */ error_callback, data, fileline_fn, From patchwork Fri Jan 20 10:54:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= X-Patchwork-Id: 1729476 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NyxJN2Vk8z23gL for ; Fri, 20 Jan 2023 21:56:36 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 520703895FFF for ; Fri, 20 Jan 2023 10:56:34 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.hazardy.de (mail.hazardy.de [78.94.181.132]) by sourceware.org (Postfix) with ESMTPS id B8FCB3858C50; Fri, 20 Jan 2023 10:54:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B8FCB3858C50 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hazardy.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hazardy.de Received: from NB-372.intranet.mimot.com (188-136-75-197-ftth-senden-dyn.heliweb.de [188.136.75.197]) by mail.hazardy.de (Postfix) with ESMTPSA id 9907C7009E7; Fri, 20 Jan 2023 11:54:18 +0100 (CET) From: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= To: gcc-patches@gcc.gnu.org, gcc@gcc.gnu.org Subject: [PATCH 4/4] libbacktrace: get debug information for loaded dlls Date: Fri, 20 Jan 2023 11:54:09 +0100 Message-Id: <20230120105409.54949-4-gcc@hazardy.de> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230120105409.54949-1-gcc@hazardy.de> References: <20230120105409.54949-1-gcc@hazardy.de> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" From: Björn Schäpers Fixes https://github.com/ianlancetaylor/libbacktrace/issues/53, except that libraries loaded after the backtrace_initialize are not handled. But as far as I can see that's the same for elf. Tested on x86_64-linux and i686-w64-mingw32. -- >8 -- * pecoff.c (coff_add): New argument for the module handle of the file, to get the base address. * pecoff.c (backtrace_initialize): Iterate over loaded libraries and call coff_add. Signed-off-by: Björn Schäpers Signed-off-by: Björn Schäpers --- libbacktrace/pecoff.c | 76 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c index 296f1357b5f..40395109e51 100644 --- a/libbacktrace/pecoff.c +++ b/libbacktrace/pecoff.c @@ -49,6 +49,7 @@ POSSIBILITY OF SUCH DAMAGE. */ #endif #include +#include #endif /* Coff file header. */ @@ -592,7 +593,8 @@ coff_syminfo (struct backtrace_state *state, uintptr_t addr, static int coff_add (struct backtrace_state *state, int descriptor, backtrace_error_callback error_callback, void *data, - fileline *fileline_fn, int *found_sym, int *found_dwarf) + fileline *fileline_fn, int *found_sym, int *found_dwarf, + uintptr_t module_handle ATTRIBUTE_UNUSED) { struct backtrace_view fhdr_view; off_t fhdr_off; @@ -623,7 +625,6 @@ coff_add (struct backtrace_state *state, int descriptor, int is_64; uintptr_t image_base; uintptr_t base_address = 0; - uintptr_t module_handle; struct dwarf_sections dwarf_sections; *found_sym = 0; @@ -871,7 +872,6 @@ coff_add (struct backtrace_state *state, int descriptor, } #ifdef HAVE_WINDOWS_H - module_handle = (uintptr_t) GetModuleHandleW (NULL); base_address = module_handle - image_base; #endif @@ -914,12 +914,80 @@ backtrace_initialize (struct backtrace_state *state, int found_sym; int found_dwarf; fileline coff_fileline_fn; + uintptr_t module_handle = 0; + +#ifdef HAVE_WINDOWS_H + DWORD i; + DWORD module_count; + DWORD bytes_needed_for_modules; + HMODULE *modules; + char module_name[MAX_PATH]; + int module_found_sym; + fileline module_fileline_fn; + + module_handle = (uintptr_t) GetModuleHandleW (NULL); +#endif ret = coff_add (state, descriptor, error_callback, data, - &coff_fileline_fn, &found_sym, &found_dwarf); + &coff_fileline_fn, &found_sym, &found_dwarf, module_handle); if (!ret) return 0; +#ifdef HAVE_WINDOWS_H + module_count = 1000; + alloc_modules: + modules = backtrace_alloc (state, module_count * sizeof(HMODULE), + error_callback, data); + if (modules == NULL) + goto skip_modules; + if (!EnumProcessModules (GetCurrentProcess (), modules, module_count, + &bytes_needed_for_modules)) + { + error_callback(data, "Could not enumerate process modules", + (int) GetLastError ()); + goto free_modules; + } + if (bytes_needed_for_modules > module_count * sizeof(HMODULE)) + { + backtrace_free (state, modules, module_count * sizeof(HMODULE), + error_callback, data); + // Add an extra of 2, if some module is loaded in another thread. + module_count = bytes_needed_for_modules / sizeof(HMODULE) + 2; + modules = NULL; + goto alloc_modules; + } + + for (i = 0; i < bytes_needed_for_modules / sizeof(HMODULE); ++i) + { + if (GetModuleFileNameA (modules[i], module_name, MAX_PATH - 1)) + { + if (strcmp (filename, module_name) == 0) + continue; + + module_handle = (uintptr_t) GetModuleHandleA (module_name); + if (module_handle == 0) + continue; + + descriptor = backtrace_open (module_name, error_callback, data, NULL); + if (descriptor < 0) + continue; + + coff_add (state, descriptor, error_callback, data, + &module_fileline_fn, &module_found_sym, &found_dwarf, + module_handle); + if (module_found_sym) + found_sym = 1; + } + } + + free_modules: + if (modules) + backtrace_free(state, modules, module_count * sizeof(HMODULE), + error_callback, data); + modules = NULL; + skip_modules: +#endif + if (!state->threaded) { if (found_sym) From patchwork Thu Jan 4 22:33:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= X-Patchwork-Id: 1882659 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T5hGv3v38z1yQ5 for ; Fri, 5 Jan 2024 09:34:47 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 649613870855 for ; Thu, 4 Jan 2024 22:34:45 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.hazardy.de (mail.hazardy.de [78.94.181.132]) by sourceware.org (Postfix) with ESMTPS id 19E4A386F805; Thu, 4 Jan 2024 22:33:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 19E4A386F805 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hazardy.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hazardy.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 19E4A386F805 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=78.94.181.132 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704407627; cv=none; b=Oqg1aGsRFRtO0ab1WwOqrRcr+jp1iumUTmgX53CTBmnB+SGQNb9GoPRk4ylPsroHYcVr/5npfNDWSxwVNxX/z0PsvomDoPM82msH9mfKSUc77qjp3Fbjdetn0mbhUKlCHiBXt+XJxu7DBBkkAse/ZarK2t6nj4hWVk7zj7cFW8w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704407627; c=relaxed/simple; bh=PqefOPPKMjGU4y8aO9QHEyimWFmlDPmlJMjylYTokaE=; h=Message-ID:Date:MIME-Version:Subject:From:To; b=DjPrvoLdzrhW+q1QECcpheN9VAW9agmO/A/aV85G2I8CN06w5YocxjDQZKmPVB1yM/p/2JqS/2u0n3oe64gucUEv8x2xoxRd/7S61OMTo+WHNorHdhjEAQsmL3iHFgn0IRPd2O95jQl/bvkfBHxITdwyC1FvzomHoTPEhjl9MAI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from [10.0.1.129] (hades.hazardy.de [10.0.1.129]) by mail.hazardy.de (Postfix) with ESMTPSA id 99C737004AC; Thu, 4 Jan 2024 23:33:27 +0100 (CET) Message-ID: Date: Thu, 4 Jan 2024 23:33:28 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 5/4] libbacktrace: improve getting debug information for loaded dlls From: =?utf-8?q?Bj=C3=B6rn_Sch=C3=A4pers?= To: Ian Lance Taylor Cc: gcc-patches@gcc.gnu.org, gcc@gcc.gnu.org References: <20230120105409.54949-1-gcc@hazardy.de> <20230120105409.54949-4-gcc@hazardy.de> <0c08e584-499f-473f-8699-a41c6a967536@hazardy.de> Content-Language: de-DE, en-US In-Reply-To: <0c08e584-499f-473f-8699-a41c6a967536@hazardy.de> X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Am 03.01.2024 um 00:12 schrieb Björn Schäpers: > Am 30.11.2023 um 20:53 schrieb Ian Lance Taylor: >> On Fri, Jan 20, 2023 at 2:55 AM Björn Schäpers wrote: >>> >>> From: Björn Schäpers >>> >>> Fixes https://github.com/ianlancetaylor/libbacktrace/issues/53, except >>> that libraries loaded after the backtrace_initialize are not handled. >>> But as far as I can see that's the same for elf. >> >> Thanks, but I don't want a patch that loops using goto statements. >> Please rewrite to avoid that.  It may be simpler to call a function. >> >> Also starting with a module count of 1000 seems like a lot.  Do >> typical Windows programs load that many modules? >> >> Ian >> >> > > Rewritten using a function. > > If that is commited, could you attribute that commit to me (--author="Björn > Schäpers ")? > > Thanks and kind regards, > Björn. I noticed that under 64 bit libraries loaded with LoadLibrary were missing. EnumProcessModules stated the correct number of modules, but did not fill the the HMODULEs, but set them to 0. While trying to investigate I noticed if I do the very same thing from main (in C++) I even got fewer module HMODULEs. So I went a different way. This detects all libraries correctly, in 32 and 64 bit. The question is, if it should be a patch on top of the previous, or should they be merged, or even only this solution and drop the EnumProcessModules variant? Kind regards, Björn. From 784e01f1baf92c23c819aeb9e77010412023700f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= Date: Thu, 4 Jan 2024 22:02:03 +0100 Subject: [PATCH 2/2] libbacktrace: improve getting debug information for loaded dlls EnumProcessModules does not always result in all modules loaded, especially those that are loaded with LoadLibrary. libbacktrace/Changelog: * configure.ac: Checked for tlhelp32.h * configure: Regenerate. * config.h.in: Regenerate. * pecoff.c: Include if available. (backtrace_initialize): Use tlhelp32 api for a snapshot to detect loaded modules. Signed-off-by: Björn Schäpers --- libbacktrace/config.h.in | 3 + libbacktrace/configure | 185 ++++++++++++++++++++------------------ libbacktrace/configure.ac | 4 + libbacktrace/pecoff.c | 62 ++++++++++++- 4 files changed, 164 insertions(+), 90 deletions(-) diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in index ee2616335c7..9b8ab88ab63 100644 --- a/libbacktrace/config.h.in +++ b/libbacktrace/config.h.in @@ -101,6 +101,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_TLHELP32_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H diff --git a/libbacktrace/configure b/libbacktrace/configure index 7ade966b54d..ca52ee3bafb 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -1866,7 +1866,7 @@ else #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. + which can conflict with char $2 (void); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ @@ -1884,7 +1884,7 @@ else #ifdef __cplusplus extern "C" #endif -char $2 (); +char $2 (void); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ @@ -1893,7 +1893,7 @@ choke me #endif int -main () +main (void) { return $2 (); ; @@ -1932,7 +1932,7 @@ else /* end confdefs.h. */ $4 int -main () +main (void) { if (sizeof ($2)) return 0; @@ -1945,7 +1945,7 @@ if ac_fn_c_try_compile "$LINENO"; then : /* end confdefs.h. */ $4 int -main () +main (void) { if (sizeof (($2))) return 0; @@ -1983,7 +1983,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; @@ -2000,7 +2000,7 @@ if ac_fn_c_try_compile "$LINENO"; then : /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; @@ -2027,7 +2027,7 @@ else /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; @@ -2044,7 +2044,7 @@ if ac_fn_c_try_compile "$LINENO"; then : /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; @@ -2079,7 +2079,7 @@ while test "x$ac_lo" != "x$ac_hi"; do /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; @@ -2104,12 +2104,12 @@ esac cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } +static long int longval (void) { return $2; } +static unsigned long int ulongval (void) { return $2; } #include #include int -main () +main (void) { FILE *f = fopen ("conftest.val", "w"); @@ -2170,7 +2170,7 @@ else /* end confdefs.h. */ $4 int -main () +main (void) { #ifndef $as_decl_name #ifdef __cplusplus @@ -3073,7 +3073,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -3213,7 +3213,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; @@ -3277,7 +3277,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -3328,7 +3328,7 @@ else /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -3369,7 +3369,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -3384,7 +3384,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -3400,7 +3400,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -3449,9 +3449,7 @@ struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; +static char *e (char **p, int i) { return p[i]; } @@ -3486,7 +3484,7 @@ int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, i int argc; char **argv; int -main () +main (void) { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; @@ -3544,7 +3542,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -3871,7 +3869,7 @@ else #include int -main () +main (void) { ; @@ -3941,7 +3939,7 @@ else #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int -main () +main (void) { int i; for (i = 0; i < 256; i++) @@ -4020,7 +4018,7 @@ else # define __EXTENSIONS__ 1 $ac_includes_default int -main () +main (void) { ; @@ -5002,7 +5000,7 @@ else /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -5043,7 +5041,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -5058,7 +5056,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -5074,7 +5072,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -5123,9 +5121,7 @@ struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; +static char *e (char **p, int i) { return p[i]; } @@ -5160,7 +5156,7 @@ int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, i int argc; char **argv; int -main () +main (void) { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; @@ -5218,7 +5214,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -7408,7 +7404,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu /* end confdefs.h. */ int -main () +main (void) { ; @@ -7994,7 +7990,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -9632,7 +9628,7 @@ _LT_EOF /* end confdefs.h. */ int -main () +main (void) { ; @@ -9672,7 +9668,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi /* end confdefs.h. */ int -main () +main (void) { ; @@ -10947,7 +10943,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -11388,9 +11384,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char dlopen (); +char dlopen (void); int -main () +main (void) { return dlopen (); ; @@ -11441,9 +11437,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char shl_load (); +char shl_load (void); int -main () +main (void) { return shl_load (); ; @@ -11484,9 +11480,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char dlopen (); +char dlopen (void); int -main () +main (void) { return dlopen (); ; @@ -11523,9 +11519,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char dlopen (); +char dlopen (void); int -main () +main (void) { return dlopen (); ; @@ -11562,9 +11558,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char dld_link (); +char dld_link (void); int -main () +main (void) { return dld_link (); ; @@ -11632,7 +11628,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11635 "configure" +#line 11631 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11738,7 +11734,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11741 "configure" +#line 11737 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12016,7 +12012,7 @@ else && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int -main () +main (void) { ; @@ -12062,7 +12058,7 @@ else && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int -main () +main (void) { ; @@ -12086,7 +12082,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int -main () +main (void) { ; @@ -12131,7 +12127,7 @@ else && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int -main () +main (void) { ; @@ -12155,7 +12151,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int -main () +main (void) { ; @@ -12228,7 +12224,7 @@ else /* end confdefs.h. */ static int f() { return 0; } int -main () +main (void) { return f(); ; @@ -12259,7 +12255,7 @@ else /* end confdefs.h. */ int -main () +main (void) { return 0; ; @@ -12312,7 +12308,7 @@ case "$host" in /* end confdefs.h. */ int -main () +main (void) { #if !defined(__SSE2__) @@ -12339,7 +12335,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { asm ("setssbsy"); ; @@ -12401,7 +12397,7 @@ else /* end confdefs.h. */ int -main () +main (void) { ; @@ -12490,7 +12486,7 @@ $as_echo_n "checking for _Unwind_GetIPInfo... " >&6; } struct _Unwind_Context *context; int ip_before_insn = 0; int -main () +main (void) { return _Unwind_GetIPInfo (context, &ip_before_insn); ; @@ -12554,7 +12550,7 @@ case "$host" in /* end confdefs.h. */ int -main () +main (void) { #if !defined(__SSE2__) @@ -12580,7 +12576,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { asm ("setssbsy"); ; @@ -12626,7 +12622,7 @@ if test x$may_have_cet = xyes; then /* end confdefs.h. */ int -main () +main (void) { return 0; ; @@ -12763,7 +12759,7 @@ else /* end confdefs.h. */ int i; int -main () +main (void) { __sync_bool_compare_and_swap (&i, i, i); __sync_lock_test_and_set (&i, 1); @@ -12805,7 +12801,7 @@ else /* end confdefs.h. */ int i; int -main () +main (void) { __atomic_load_n (&i, __ATOMIC_ACQUIRE); __atomic_store_n (&i, 1, __ATOMIC_RELEASE); @@ -12843,7 +12839,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int i; int -main () +main (void) { int j; ; @@ -13521,6 +13517,21 @@ fi done +for ac_header in tlhelp32.h +do : + ac_fn_c_check_header_compile "$LINENO" "tlhelp32.h" "ac_cv_header_tlhelp32_h" "#ifdef HAVE_WINDOWS_H +# include +#endif +" +if test "x$ac_cv_header_tlhelp32_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TLHELP32_H 1 +_ACEOF + +fi + +done + # Check for the fcntl function. if test -n "${with_target_subdir}"; then @@ -13625,7 +13636,7 @@ else #include int -main () +main (void) { int mib0 = CTL_KERN; int mib1 = KERN_PROC; int mib2 = KERN_PROC_PATHNAME; ; @@ -13659,7 +13670,7 @@ else #include int -main () +main (void) { int mib0 = CTL_KERN; int mib1 = KERN_PROC_ARGS; int mib2 = KERN_PROC_PATHNAME; ; @@ -13715,9 +13726,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char clock_gettime (); +char clock_gettime (void); int -main () +main (void) { return clock_gettime (); ; @@ -13792,7 +13803,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int i; int -main () +main (void) { return 0; ; @@ -13835,9 +13846,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char compress (); +char compress (void); int -main () +main (void) { return compress (); ; @@ -13881,7 +13892,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -13919,7 +13930,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -13962,9 +13973,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char ZSTD_compress (); +char ZSTD_compress (void); int -main () +main (void) { return ZSTD_compress (); ; @@ -14008,7 +14019,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -14338,9 +14349,9 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char lzma_auto_decoder (); +char lzma_auto_decoder (void); int -main () +main (void) { return lzma_auto_decoder (); ; @@ -14385,7 +14396,7 @@ else /* end confdefs.h. */ int -main () +main (void) { return 0; ; diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 0f61f2b28ab..b9a695ab402 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -380,6 +380,10 @@ if test "$have_loadquery" = "yes"; then fi AC_CHECK_HEADERS(windows.h) +AC_CHECK_HEADERS(tlhelp32.h, [], [], +[#ifdef HAVE_WINDOWS_H +# include +#endif]) # Check for the fcntl function. if test -n "${with_target_subdir}"; then diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c index 64787a18411..647baa39640 100644 --- a/libbacktrace/pecoff.c +++ b/libbacktrace/pecoff.c @@ -50,6 +50,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #include #include + +#ifdef HAVE_TLHELP32_H +#include + +#ifdef UNICODE +/* If UNICODE is defined, all the symbols are replaced by a macro to use the + wide variant. But we need the ansi variant, so undef the macros. */ +#undef MODULEENTRY32 +#undef Module32First +#undef Module32Next +#endif +#endif #endif /* Coff file header. */ @@ -900,7 +912,7 @@ coff_add (struct backtrace_state *state, int descriptor, return 0; } -#ifdef HAVE_WINDOWS_H +#if defined(HAVE_WINDOWS_H) && !defined(HAVE_TLHELP32_H) static void free_modules (struct backtrace_state *state, backtrace_error_callback error_callback, void *data, @@ -964,13 +976,19 @@ backtrace_initialize (struct backtrace_state *state, uintptr_t module_handle = 0; #ifdef HAVE_WINDOWS_H + fileline module_fileline_fn; + int module_found_sym; + +#ifdef HAVE_TLHELP32_H + HANDLE snapshot; +#else DWORD i; DWORD module_count = 100; DWORD bytes_allocated_for_modules = 0; HMODULE *modules = NULL; char module_name[MAX_PATH]; - int module_found_sym; - fileline module_fileline_fn; + +#endif module_handle = (uintptr_t) GetModuleHandle (NULL); #endif @@ -981,6 +999,43 @@ backtrace_initialize (struct backtrace_state *state, return 0; #ifdef HAVE_WINDOWS_H +#ifdef HAVE_TLHELP32_H + do + { + snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); + } + while (snapshot == INVALID_HANDLE_VALUE + && GetLastError () == ERROR_BAD_LENGTH); + + if (snapshot != INVALID_HANDLE_VALUE) + { + MODULEENTRY32 entry; + BOOL ok; + entry.dwSize = sizeof(MODULEENTRY32); + + for (ok = Module32First (snapshot, &entry); ok; ok =Module32Next (snapshot, &entry)) + { + if (strcmp (filename, entry.szExePath) == 0) + continue; + + module_handle = (uintptr_t) entry.hModule; + if (module_handle == 0) + continue; + + descriptor = backtrace_open (entry.szExePath, error_callback, data, NULL); + if (descriptor < 0) + continue; + + coff_add (state, descriptor, error_callback, data, + &module_fileline_fn, &module_found_sym, &found_dwarf, + module_handle); + if (module_found_sym) + found_sym = 1; + } + + CloseHandle (snapshot); + } +#else get_all_modules (state, error_callback, data, &modules, &module_count, &bytes_allocated_for_modules); @@ -1009,6 +1064,7 @@ backtrace_initialize (struct backtrace_state *state, if (modules) free_modules (state, error_callback, data, &modules, bytes_allocated_for_modules); +#endif #endif if (!state->threaded)