Index: configure.ac =================================================================== --- configure.ac (revision 193259) +++ configure.ac (working copy) @@ -289,6 +289,19 @@ fi AC_CHECK_DECLS(strnlen) +# Check for getexecname function. +if test -n "${with_target_subdir}"; then + case "${host}" in + *-*-solaris2*) have_getexecname=yes ;; + *) have_getexecname=no ;; + esac +else + AC_CHECK_FUNC(getexecname, [have_getexecname=yes], [have_getexecname=no]) +fi +if test "$have_getexecname" = "yes"; then + AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.]) +fi + AC_CACHE_CHECK([whether tests can run], [libbacktrace_cv_sys_native], [AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])], Index: fileline.c =================================================================== --- fileline.c (revision 193259) +++ fileline.c (working copy) @@ -34,12 +34,17 @@ POSSIBILITY OF SUCH DAMAGE. */ #include #include +#include #include #include #include "backtrace.h" #include "internal.h" +#ifndef HAVE_GETEXECNAME +#define getexecname() NULL +#endif + /* Initialize the fileline information from the executable. Returns 1 on success, 0 on failure. */ @@ -49,6 +54,8 @@ fileline_initialize (struct backtrace_st { int failed; fileline fileline_fn; + int pass; + int called_error_callback; int descriptor; failed = state->fileline_initialization_failed; @@ -79,12 +86,58 @@ fileline_initialize (struct backtrace_st /* We have not initialized the information. Do it now. */ - if (state->filename != NULL) - descriptor = backtrace_open (state->filename, error_callback, data, NULL); - else - descriptor = backtrace_open ("/proc/self/exe", error_callback, data, NULL); + descriptor = -1; + called_error_callback = 0; + for (pass = 0; pass < 4; ++pass) + { + const char *filename; + int does_not_exist; + + switch (pass) + { + case 0: + filename = state->filename; + break; + case 1: + filename = getexecname (); + break; + case 2: + filename = "/proc/self/exe"; + break; + case 3: + filename = "/proc/curproc/file"; + break; + default: + abort (); + } + + if (filename == NULL) + continue; + + descriptor = backtrace_open (filename, error_callback, data, + &does_not_exist); + if (descriptor < 0 && !does_not_exist) + { + called_error_callback = 1; + break; + } + if (descriptor >= 0) + break; + } + if (descriptor < 0) - failed = 1; + { + if (!called_error_callback) + { + if (state->filename != NULL) + error_callback (data, state->filename, ENOENT); + else + error_callback (data, + "libbacktrace could not find executable to open", + 0); + } + failed = 1; + } if (!failed) { Index: print.c =================================================================== --- print.c (revision 193259) +++ print.c (working copy) @@ -69,12 +69,10 @@ static void error_callback (void *data, const char *msg, int errnum) { struct print_data *pdata = (struct print_data *) data; - const char *name; - name = pdata->state->filename; - if (name == NULL) - name = "/proc/self/exe"; - fprintf (stderr, "%s: libbacktrace: %s", name, msg); + if (pdata->state->filename != NULL) + fprintf (stderr, "%s: ", pdata->state->filename); + fprintf (stderr, "libbacktrace: %s", msg); if (errnum > 0) fprintf (stderr, ": %s", strerror (errnum)); fputc ('\n', stderr);