mirror of
https://github.com/ianlancetaylor/libbacktrace.git
synced 2026-03-29 13:39:07 +08:00
libbacktrace: support fetching executable name using sysctl
This supports FreeBSD and NetBSD when /proc is not mounted.
This commit is contained in:
@@ -34,6 +34,14 @@
|
|||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#undef HAVE_INTTYPES_H
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have KERN_PROC and KERN_PROC_PATHNAME in <sys/sysctl.h>.
|
||||||
|
*/
|
||||||
|
#undef HAVE_KERN_PROC
|
||||||
|
|
||||||
|
/* Define to 1 if you have KERN_PROCARGS and KERN_PROC_PATHNAME in
|
||||||
|
<sys/sysctl.h>. */
|
||||||
|
#undef HAVE_KERN_PROC_ARGS
|
||||||
|
|
||||||
/* Define to 1 if you have the <link.h> header file. */
|
/* Define to 1 if you have the <link.h> header file. */
|
||||||
#undef HAVE_LINK_H
|
#undef HAVE_LINK_H
|
||||||
|
|
||||||
|
|||||||
70
configure
vendored
70
configure
vendored
@@ -12469,6 +12469,76 @@ $as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check for sysctl definitions.
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for KERN_PROC" >&5
|
||||||
|
$as_echo_n "checking for KERN_PROC... " >&6; }
|
||||||
|
if ${libbacktrace_cv_proc+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int mib0 = CTL_KERN; int mib1 = KERN_PROC; int mib2 = KERN_PROC_PATHNAME;
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"; then :
|
||||||
|
libbacktrace_cv_proc=yes
|
||||||
|
else
|
||||||
|
libbacktrace_cv_proc=no
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libbacktrace_cv_proc" >&5
|
||||||
|
$as_echo "$libbacktrace_cv_proc" >&6; }
|
||||||
|
if test "$libbacktrace_cv_proc" = "yes"; then
|
||||||
|
|
||||||
|
$as_echo "#define HAVE_KERN_PROC 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for KERN_PROG_ARGS" >&5
|
||||||
|
$as_echo_n "checking for KERN_PROG_ARGS... " >&6; }
|
||||||
|
if ${libbacktrace_cv_procargs+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int mib0 = CTL_KERN; int mib1 = KERN_PROC_ARGS; int mib2 = KERN_PROC_PATHNAME;
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"; then :
|
||||||
|
libbacktrace_cv_procargs=yes
|
||||||
|
else
|
||||||
|
libbacktrace_cv_procargs=no
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libbacktrace_cv_procargs" >&5
|
||||||
|
$as_echo "$libbacktrace_cv_procargs" >&6; }
|
||||||
|
if test "$libbacktrace_cv_procargs" = "yes"; then
|
||||||
|
|
||||||
|
$as_echo "#define HAVE_KERN_PROC_ARGS 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
# Check for the clock_gettime function.
|
# Check for the clock_gettime function.
|
||||||
for ac_func in clock_gettime
|
for ac_func in clock_gettime
|
||||||
do :
|
do :
|
||||||
|
|||||||
30
configure.ac
30
configure.ac
@@ -395,6 +395,36 @@ if test "$have_getexecname" = "yes"; then
|
|||||||
AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.])
|
AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check for sysctl definitions.
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([for KERN_PROC],
|
||||||
|
[libbacktrace_cv_proc],
|
||||||
|
[AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
], [int mib0 = CTL_KERN; int mib1 = KERN_PROC; int mib2 = KERN_PROC_PATHNAME;])],
|
||||||
|
[libbacktrace_cv_proc=yes],
|
||||||
|
[libbacktrace_cv_proc=no])])
|
||||||
|
if test "$libbacktrace_cv_proc" = "yes"; then
|
||||||
|
AC_DEFINE([HAVE_KERN_PROC], 1,
|
||||||
|
[Define to 1 if you have KERN_PROC and KERN_PROC_PATHNAME in <sys/sysctl.h>.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([for KERN_PROG_ARGS],
|
||||||
|
[libbacktrace_cv_procargs],
|
||||||
|
[AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
], [int mib0 = CTL_KERN; int mib1 = KERN_PROC_ARGS; int mib2 = KERN_PROC_PATHNAME;])],
|
||||||
|
[libbacktrace_cv_procargs=yes],
|
||||||
|
[libbacktrace_cv_procargs=no])])
|
||||||
|
if test "$libbacktrace_cv_procargs" = "yes"; then
|
||||||
|
AC_DEFINE([HAVE_KERN_PROC_ARGS], 1,
|
||||||
|
[Define to 1 if you have KERN_PROCARGS and KERN_PROC_PATHNAME in <sys/sysctl.h>.])
|
||||||
|
fi
|
||||||
|
|
||||||
# Check for the clock_gettime function.
|
# Check for the clock_gettime function.
|
||||||
AC_CHECK_FUNCS(clock_gettime)
|
AC_CHECK_FUNCS(clock_gettime)
|
||||||
clock_gettime_link=
|
clock_gettime_link=
|
||||||
|
|||||||
84
fileline.c
84
fileline.c
@@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_KERN_PROC_ARGS) || defined (HAVE_KERN_PROC)
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@@ -46,6 +50,78 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||||||
#define getexecname() NULL
|
#define getexecname() NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined (HAVE_KERN_PROC_ARGS) && !defined (HAVE_KERN_PROC)
|
||||||
|
|
||||||
|
#define sysctl_exec_name1(state, error_callback, data) NULL
|
||||||
|
#define sysctl_exec_name2(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#else /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
sysctl_exec_name (struct backtrace_state *state,
|
||||||
|
int mib0, int mib1, int mib2, int mib3,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
int mib[4];
|
||||||
|
size_t len;
|
||||||
|
char *name;
|
||||||
|
size_t rlen;
|
||||||
|
|
||||||
|
mib[0] = mib0;
|
||||||
|
mib[1] = mib1;
|
||||||
|
mib[2] = mib2;
|
||||||
|
mib[3] = mib3;
|
||||||
|
|
||||||
|
if (sysctl (mib, 4, NULL, &len, NULL, 0) < 0)
|
||||||
|
return NULL;
|
||||||
|
name = (char *) backtrace_alloc (state, len, error_callback, data);
|
||||||
|
if (name == NULL)
|
||||||
|
return NULL;
|
||||||
|
rlen = len;
|
||||||
|
if (sysctl (mib, 4, name, &rlen, NULL, 0) < 0)
|
||||||
|
{
|
||||||
|
backtrace_free (state, name, len, error_callback, data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_KERN_PROC_ARGS
|
||||||
|
|
||||||
|
static char *
|
||||||
|
sysctl_exec_name1 (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
/* This variant is used on NetBSD. */
|
||||||
|
return sysctl_exec_name (state, CTL_KERN, KERN_PROC_ARGS, -1,
|
||||||
|
KERN_PROC_PATHNAME, error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define sysctl_exec_name1(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_KERN_PROC
|
||||||
|
|
||||||
|
static char *
|
||||||
|
sysctl_exec_name2 (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
/* This variant is used on FreeBSD. */
|
||||||
|
return sysctl_exec_name (state, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1,
|
||||||
|
error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define sysctl_exec_name2(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
|
||||||
|
|
||||||
/* Initialize the fileline information from the executable. Returns 1
|
/* Initialize the fileline information from the executable. Returns 1
|
||||||
on success, 0 on failure. */
|
on success, 0 on failure. */
|
||||||
|
|
||||||
@@ -83,7 +159,7 @@ fileline_initialize (struct backtrace_state *state,
|
|||||||
|
|
||||||
descriptor = -1;
|
descriptor = -1;
|
||||||
called_error_callback = 0;
|
called_error_callback = 0;
|
||||||
for (pass = 0; pass < 5; ++pass)
|
for (pass = 0; pass < 7; ++pass)
|
||||||
{
|
{
|
||||||
int does_not_exist;
|
int does_not_exist;
|
||||||
|
|
||||||
@@ -106,6 +182,12 @@ fileline_initialize (struct backtrace_state *state,
|
|||||||
(long) getpid ());
|
(long) getpid ());
|
||||||
filename = buf;
|
filename = buf;
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
filename = sysctl_exec_name1 (state, error_callback, data);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
filename = sysctl_exec_name2 (state, error_callback, data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user