This libbacktrace patch, based on one by Andres Freund, uses the _pgmptr variable declared on Windows to find the executable file name if none is specified. Bootstrapped and ran libbacktrace testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian Patch from Andres Freund: * configure.ac: Check for _pgmptr declaration. * fileline.c (fileline_initialize): Check for _pgmfptr before /proc/self/exec. * configure, config.h.in: Regenerate.
a349ba16f18b66b70c7a1bdb1ab5c5b6247676da diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 39e6bf41e35..72ff2b30053 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -407,6 +407,9 @@ if test "$have_getexecname" = "yes"; then AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.]) fi +# Check for _pgmptr variable, contains the executable filename on windows +AC_CHECK_DECLS([_pgmptr]) + # Check for sysctl definitions. AC_CACHE_CHECK([for KERN_PROC], diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c index 674bf33cdcf..0e560b44e7a 100644 --- a/libbacktrace/fileline.c +++ b/libbacktrace/fileline.c @@ -155,6 +155,16 @@ macho_get_executable_path (struct backtrace_state *state, #endif /* !defined (HAVE_MACH_O_DYLD_H) */ +#if HAVE_DECL__PGMPTR + +#define windows_executable_filename() _pgmptr + +#else /* !HAVE_DECL__PGMPTR */ + +#define windows_executable_filename() NULL + +#endif /* !HAVE_DECL__PGMPTR */ + /* Initialize the fileline information from the executable. Returns 1 on success, 0 on failure. */ @@ -192,7 +202,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; @@ -205,23 +215,28 @@ fileline_initialize (struct backtrace_state *state, filename = getexecname (); break; case 2: - filename = "/proc/self/exe"; + /* Test this before /proc/self/exe, as the latter exists but points + to the wine binary (and thus doesn't work). */ + filename = windows_executable_filename (); break; case 3: - filename = "/proc/curproc/file"; + filename = "/proc/self/exe"; break; case 4: + filename = "/proc/curproc/file"; + break; + case 5: snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out", (long) getpid ()); filename = buf; break; - case 5: + case 6: filename = sysctl_exec_name1 (state, error_callback, data); break; - case 6: + case 7: filename = sysctl_exec_name2 (state, error_callback, data); break; - case 7: + case 8: filename = macho_get_executable_path (state, error_callback, data); break; default: