summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbacktrace/ChangeLog13
-rw-r--r--libbacktrace/config.h.in3
-rwxr-xr-xlibbacktrace/configure21
-rw-r--r--libbacktrace/configure.ac13
-rw-r--r--libbacktrace/fileline.c63
-rw-r--r--libbacktrace/print.c8
6 files changed, 111 insertions, 10 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index 91e1c9eccd4..dcd49d071d6 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,16 @@
+2012-11-12 Ian Lance Taylor <iant@google.com>
+ Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+ Gerald Pfeifer <gerald@pfeifer.com>
+
+ * configure.ac: Check for getexecname.
+ * fileline.c: #include <errno.h>. Define getexecname if not
+ available.
+ (fileline_initialize): Try to find the executable in a few
+ different ways.
+ * print.c (error_callback): Only print the filename if it came
+ from the backtrace state.
+ * configure, config.h.in: Rebuild.
+
2012-10-29 Ian Lance Taylor <iant@google.com>
* mmap.c (backtrace_vector_release): Correct last patch: add
diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in
index ba564a82e85..48ff63fdc05 100644
--- a/libbacktrace/config.h.in
+++ b/libbacktrace/config.h.in
@@ -16,6 +16,9 @@
/* Define to 1 if you have the fcntl function */
#undef HAVE_FCNTL
+/* Define if getexecname is available. */
+#undef HAVE_GETEXECNAME
+
/* Define if _Unwind_GetIPInfo is available. */
#undef HAVE_GETIPINFO
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 1f6a97b34ae..2a57c5102f3 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -12319,6 +12319,27 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# Check for getexecname function.
+if test -n "${with_target_subdir}"; then
+ case "${host}" in
+ *-*-solaris2*) have_getexecname=yes ;;
+ *) have_getexecname=no ;;
+ esac
+else
+ ac_fn_c_check_func "$LINENO" "getexecname" "ac_cv_func_getexecname"
+if test "x$ac_cv_func_getexecname" = x""yes; then :
+ have_getexecname=yes
+else
+ have_getexecname=no
+fi
+
+fi
+if test "$have_getexecname" = "yes"; then
+
+$as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h
+
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether tests can run" >&5
$as_echo_n "checking whether tests can run... " >&6; }
if test "${libbacktrace_cv_sys_native+set}" = set; then :
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 534f9276cdb..c9cba3e4e9c 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -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;])],
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index e577ecc9061..1ade81e9d49 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -34,12 +34,17 @@ POSSIBILITY OF SUCH DAMAGE. */
#include <sys/types.h>
#include <sys/stat.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#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_state *state,
{
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_state *state,
/* 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)
{
diff --git a/libbacktrace/print.c b/libbacktrace/print.c
index 2d9d76aeba7..9b775584d47 100644
--- a/libbacktrace/print.c
+++ b/libbacktrace/print.c
@@ -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);