Skip to content

Commit

Permalink
libbacktrace: load Windows modules
Browse files Browse the repository at this point in the history
Patch from Björn Schäpers <[email protected]>.

	* configure.ac: Checked for tlhelp32.h
	* pecoff.c: Include <tlhelp32.h> if available.
	(backtrace_initialize): Use tlhelp32 api for a snapshot to
	detect loaded modules.
	(coff_add): New argument for the module handle of the file,
	to get the base address.
	* configure, config.h.in: Regenerate.
  • Loading branch information
ianlancetaylor committed May 1, 2024
1 parent ae1e707 commit 0e933e7
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 8 deletions.
3 changes: 3 additions & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
15 changes: 15 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -12454,6 +12454,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
Expand Down
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,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
Expand Down
73 changes: 65 additions & 8 deletions pecoff.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 0e933e7

Please sign in to comment.