diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in index ee2616335c7f55d5784899ea8942b247bf2bbe37..9b8ab88ab630ed927d1f92ac2ac220beb41e7ab3 100644 --- a/libbacktrace/config.h.in +++ b/libbacktrace/config.h.in @@ -101,6 +101,9 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <tlhelp32.h> header file. */ +#undef HAVE_TLHELP32_H + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H diff --git a/libbacktrace/configure b/libbacktrace/configure index d6d6606a72c74353bbef449328ebf4840c1b02ec..ab94a85f45c1525a90bac2396a1a9885acb31f15 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -13523,6 +13523,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 <windows.h> +#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 diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 3e0075a2b7930e11d1562a722bdafb09ca96b0dc..59e9c415db8f74d848e6c331667b25bea23f191d 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 <windows.h> +#endif]) # Check for the fcntl function. if test -n "${with_target_subdir}"; then diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c index 9e437d810c73a115c5bbfa16359d693b997da29b..4f2678411785aee0ac8f704115c6a8fbf24bd45c 100644 --- a/libbacktrace/pecoff.c +++ b/libbacktrace/pecoff.c @@ -49,6 +49,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #endif #include <windows.h> + +#ifdef HAVE_TLHELP32_H +#include <tlhelp32.h> + +#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. */ @@ -592,7 +604,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; @@ -870,12 +883,7 @@ coff_add (struct backtrace_state *state, int descriptor, } #ifdef HAVE_WINDOWS_H - { - uintptr_t module_handle; - - module_handle = (uintptr_t) GetModuleHandle (NULL); - base_address = module_handle - image_base; - } + base_address = module_handle - image_base; #endif if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, @@ -917,12 +925,61 @@ backtrace_initialize (struct backtrace_state *state, int found_sym; int found_dwarf; fileline coff_fileline_fn; + uintptr_t module_handle = 0; +#ifdef HAVE_TLHELP32_H + fileline module_fileline_fn; + int module_found_sym; + HANDLE snapshot; +#endif + +#ifdef HAVE_WINDOWS_H + module_handle = (uintptr_t) GetModuleHandle (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_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); + } +#endif + if (!state->threaded) { if (found_sym)