libbacktrace: support fetching executable name using sysctl

This supports FreeBSD and NetBSD when /proc is not mounted.

libbacktrace/
	* fileline.c (sysctl_exec_name): New static function.
	(sysctl_exec_name1): New macro or static function.
	(sysctl_exec_name2): Likewise.
	(fileline_initialize): Try sysctl_exec_name[12].
	* configure.ac: Check for sysctl args to fetch executable name.
	* configure: Regenerate.
	* config.h.in: Regenerate.
This commit is contained in:
Ian Lance Taylor 2020-02-15 15:29:02 -08:00
parent 925b418e06
commit 261356844a
5 changed files with 201 additions and 1 deletions

View File

@ -1,3 +1,13 @@
2020-05-08 Ian Lance Taylor <iant@golang.org>
* fileline.c (sysctl_exec_name): New static function.
(sysctl_exec_name1): New macro or static function.
(sysctl_exec_name2): Likewise.
(fileline_initialize): Try sysctl_exec_name[12].
* configure.ac: Check for sysctl args to fetch executable name.
* configure: Regenerate.
* config.h.in: Regenerate.
2020-02-15 Ian Lance Taylor <iant@golang.org>
* ztest.c (test_large): Update file to current libgo test file.

View File

@ -34,6 +34,14 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#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. */
#undef HAVE_LINK_H

View File

@ -13182,6 +13182,76 @@ $as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h
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.
for ac_func in clock_gettime
do :

View File

@ -388,6 +388,36 @@ if test "$have_getexecname" = "yes"; then
AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.])
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.
AC_CHECK_FUNCS(clock_gettime)
clock_gettime_link=

View File

@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE. */
#include <stdlib.h>
#include <unistd.h>
#if defined (HAVE_KERN_PROC_ARGS) || defined (HAVE_KERN_PROC)
#include <sys/sysctl.h>
#endif
#include "backtrace.h"
#include "internal.h"
@ -46,6 +50,78 @@ POSSIBILITY OF SUCH DAMAGE. */
#define getexecname() NULL
#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
on success, 0 on failure. */
@ -83,7 +159,7 @@ fileline_initialize (struct backtrace_state *state,
descriptor = -1;
called_error_callback = 0;
for (pass = 0; pass < 5; ++pass)
for (pass = 0; pass < 7; ++pass)
{
int does_not_exist;
@ -106,6 +182,12 @@ fileline_initialize (struct backtrace_state *state,
(long) getpid ());
filename = buf;
break;
case 5:
filename = sysctl_exec_name1 (state, error_callback, data);
break;
case 6:
filename = sysctl_exec_name2 (state, error_callback, data);
break;
default:
abort ();
}