mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Improve the backtrace to print symbols when backtrace_symbols() is available
The previous commit removed the code related to the internal symbol table. On platforms where available, we can now use backtrace_symbols() to print more verbose symbols table to the output. As there's now general availability of backtrace() and backtrace_symbols() functions (see below), the commit also removes the usage of glibc internals and the custom stack tracing. * backtrace(), backtrace_symbols(), and backtrace_symbols_fd() are provided in glibc since version 2.1. * backtrace(), backtrace_symbols(), and backtrace_symbols_fd() first appeared in Mac OS X 10.5. * The backtrace() library of functions first appeared in NetBSD 7.0 and FreeBSD 10.0.
This commit is contained in:
parent
ad5250ff9c
commit
e847591867
9 changed files with 118 additions and 230 deletions
|
|
@ -197,7 +197,7 @@ static void
|
|||
assertion_failed(const char *file, int line, isc_assertiontype_t type,
|
||||
const char *cond) {
|
||||
void *tracebuf[BACKTRACE_MAXFRAME];
|
||||
int i, nframes;
|
||||
int nframes;
|
||||
isc_result_t result;
|
||||
const char *logsuffix = "";
|
||||
|
||||
|
|
@ -222,12 +222,22 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
|
|||
"%s:%d: %s(%s) failed%s", file, line,
|
||||
isc_assertion_typetotext(type), cond, logsuffix);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
for (i = 0; i < nframes; i++) {
|
||||
#if HAVE_BACKTRACE_SYMBOLS
|
||||
char **strs = backtrace_symbols(tracebuf, nframes);
|
||||
for (int i = 0; i < nframes; i++) {
|
||||
isc_log_write(named_g_lctx,
|
||||
NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_MAIN,
|
||||
ISC_LOG_CRITICAL, "%s", strs[i]);
|
||||
}
|
||||
#else /* HAVE_BACKTRACE_SYMBOLS */
|
||||
for (int i = 0; i < nframes; i++) {
|
||||
isc_log_write(
|
||||
named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
|
||||
"#%d %p in ??", i, tracebuf[i]);
|
||||
}
|
||||
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
||||
}
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
|
|||
|
||||
CDEFINES =
|
||||
CWARNINGS =
|
||||
BACKTRACECFLAGS = @BACKTRACECFLAGS@
|
||||
|
||||
DNSLIBS = ../../lib/dns/libdns.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@
|
||||
ISCLIBS = ../../lib/isc/libisc.@A@ ${OPENSSL_LIBS} ${JSON_C_LIBS} ${LIBXML2_LIBS} ${ZLIB_LIBS}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
|
|||
CDEFINES = @USE_GSSAPI@
|
||||
|
||||
CWARNINGS =
|
||||
BACKTRACECFLAGS = @BACKTRACECFLAGS@
|
||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||
|
||||
DNSLIBS = ../../../lib/dns/libdns.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@
|
||||
|
|
@ -97,7 +96,7 @@ XSRCS = adb_test.c \
|
|||
@BIND9_MAKE_RULES@
|
||||
|
||||
# disable optimization for backtrace test to get the expected result
|
||||
BTTEST_CFLAGS = ${BACKTRACECFLAGS} ${EXT_CFLAGS} ${ALL_CPPFLAGS} -g \
|
||||
BTTEST_CFLAGS = ${EXT_CFLAGS} ${ALL_CPPFLAGS} -g \
|
||||
${ALWAYS_WARNINGS} ${STD_CWARNINGS} ${CWARNINGS} ${PTHREAD_CFLAGS}
|
||||
|
||||
all_tests: ${XTARGETS}
|
||||
|
|
|
|||
15
config.h.in
15
config.h.in
|
|
@ -45,6 +45,12 @@
|
|||
/* define if the ARM yield instruction is available */
|
||||
#undef HAVE_ARM_YIELD
|
||||
|
||||
/* Define to 1 if you have the `backtrace' function. */
|
||||
#undef HAVE_BACKTRACE
|
||||
|
||||
/* Define to 1 if you have the `backtrace_symbols' function. */
|
||||
#undef HAVE_BACKTRACE_SYMBOLS
|
||||
|
||||
/* Define to 1 if the compiler supports __builtin_clz. */
|
||||
#undef HAVE_BUILTIN_CLZ
|
||||
|
||||
|
|
@ -150,6 +156,9 @@
|
|||
/* Define to 1 if you have the `EVP_sha512' function. */
|
||||
#undef HAVE_EVP_SHA512
|
||||
|
||||
/* Define to 1 if you have the <execinfo.h> header file. */
|
||||
#undef HAVE_EXECINFO_H
|
||||
|
||||
/* Define to 1 if you have the `explicit_bzero' function. */
|
||||
#undef HAVE_EXPLICIT_BZERO
|
||||
|
||||
|
|
@ -231,9 +240,6 @@
|
|||
/* Define to 1 if you have the <krb5/krb5.h> header file. */
|
||||
#undef HAVE_KRB5_KRB5_H
|
||||
|
||||
/* define if system have backtrace function */
|
||||
#undef HAVE_LIBCTRACE
|
||||
|
||||
/* Define if libidn2 was found */
|
||||
#undef HAVE_LIBIDN2
|
||||
|
||||
|
|
@ -549,9 +555,6 @@
|
|||
/* Define to use default system tuning. */
|
||||
#undef TUNE_LARGE
|
||||
|
||||
/* define if we can use backtrace */
|
||||
#undef USE_BACKTRACE
|
||||
|
||||
/* Enable DNS Response Policy Service API */
|
||||
#undef USE_DNSRPS
|
||||
|
||||
|
|
|
|||
96
configure
vendored
96
configure
vendored
|
|
@ -775,7 +775,6 @@ XTARGETS
|
|||
PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
BACKTRACECFLAGS
|
||||
CCNOOPT
|
||||
CCOPT
|
||||
STD_CWARNINGS
|
||||
|
|
@ -920,7 +919,6 @@ with_json_c
|
|||
with_zlib
|
||||
with_purify
|
||||
with_gperftools_profiler
|
||||
enable_backtrace
|
||||
enable_tcp_fastopen
|
||||
with_readline
|
||||
enable_isc_spnego
|
||||
|
|
@ -1626,7 +1624,6 @@ Optional Features:
|
|||
pthread rwlock
|
||||
--enable-fips-mode enable FIPS mode in OpenSSL library [default=no]
|
||||
--enable-native-pkcs11 use native PKCS11 for public-key crypto [default=no]
|
||||
--enable-backtrace log stack backtrace on abort [default=yes]
|
||||
--disable-tcp-fastopen disable TCP Fast Open support [default=yes]
|
||||
--disable-isc-spnego use SPNEGO from GSSAPI library
|
||||
--disable-chroot disable chroot
|
||||
|
|
@ -12088,7 +12085,6 @@ fi
|
|||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Use pkg-config
|
||||
#
|
||||
|
|
@ -18681,42 +18677,88 @@ $as_echo "no" >&6; }
|
|||
esac
|
||||
|
||||
#
|
||||
# enable/disable dumping stack backtrace. Also check if the system supports
|
||||
# glibc-compatible backtrace() function.
|
||||
# Check if the system supports glibc-compatible backtrace() function.
|
||||
#
|
||||
# Check whether --enable-backtrace was given.
|
||||
if test "${enable_backtrace+set}" = set; then :
|
||||
enableval=$enable_backtrace;
|
||||
for ac_header in execinfo.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_execinfo_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_EXECINFO_H 1
|
||||
_ACEOF
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing backtrace" >&5
|
||||
$as_echo_n "checking for library containing backtrace... " >&6; }
|
||||
if ${ac_cv_search_backtrace+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
enable_backtrace="yes"
|
||||
fi
|
||||
|
||||
|
||||
if test "$enable_backtrace" = "yes"; then :
|
||||
|
||||
$as_echo "#define USE_BACKTRACE 1" >>confdefs.h
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <execinfo.h>
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char backtrace ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return (backtrace((void **)0, 0));
|
||||
|
||||
return backtrace ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
|
||||
$as_echo "#define HAVE_LIBCTRACE 1" >>confdefs.h
|
||||
|
||||
|
||||
for ac_lib in '' execinfo; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_backtrace=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_backtrace+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_backtrace+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_backtrace=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_backtrace" >&5
|
||||
$as_echo "$ac_cv_search_backtrace" >&6; }
|
||||
ac_res=$ac_cv_search_backtrace
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
for ac_func in backtrace backtrace_symbols
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
# AM_CONDITIONAL([HAVE_BACKTRACE], [test "$ac_cv_func_backtrace" = "yes"])
|
||||
|
||||
#
|
||||
# File name extension for static archive files, for those few places
|
||||
|
|
|
|||
21
configure.ac
21
configure.ac
|
|
@ -56,7 +56,6 @@ AC_SUBST(STD_CDEFINES)
|
|||
AC_SUBST(STD_CWARNINGS)
|
||||
AC_SUBST(CCOPT)
|
||||
AC_SUBST(CCNOOPT)
|
||||
AC_SUBST(BACKTRACECFLAGS)
|
||||
|
||||
#
|
||||
# Use pkg-config
|
||||
|
|
@ -1425,23 +1424,13 @@ case $use_profiler in
|
|||
esac
|
||||
|
||||
#
|
||||
# enable/disable dumping stack backtrace. Also check if the system supports
|
||||
# glibc-compatible backtrace() function.
|
||||
# Check if the system supports glibc-compatible backtrace() function.
|
||||
#
|
||||
AC_ARG_ENABLE([backtrace],
|
||||
[AS_HELP_STRING([--enable-backtrace],
|
||||
[log stack backtrace on abort [default=yes]])],
|
||||
[], [enable_backtrace="yes"])
|
||||
AC_CHECK_HEADERS([execinfo.h],
|
||||
[AC_SEARCH_LIBS([backtrace], [execinfo],
|
||||
[AC_CHECK_FUNCS([backtrace backtrace_symbols])])])
|
||||
|
||||
AS_IF([test "$enable_backtrace" = "yes"],
|
||||
[AC_DEFINE([USE_BACKTRACE], [1], [define if we can use backtrace])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <execinfo.h>]],
|
||||
[[return (backtrace((void **)0, 0));]]
|
||||
)],
|
||||
[AC_DEFINE([HAVE_LIBCTRACE], [1], [define if system have backtrace function])]
|
||||
)])
|
||||
# AM_CONDITIONAL([HAVE_BACKTRACE], [test "$ac_cv_func_backtrace" = "yes"])
|
||||
|
||||
#
|
||||
# File name extension for static archive files, for those few places
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ static void
|
|||
default_callback(const char *file, int line, isc_assertiontype_t type,
|
||||
const char *cond) {
|
||||
void *tracebuf[BACKTRACE_MAXFRAME];
|
||||
int i, nframes;
|
||||
int nframes;
|
||||
const char *logsuffix = ".";
|
||||
isc_result_t result;
|
||||
|
||||
|
|
@ -108,9 +108,16 @@ default_callback(const char *file, int line, isc_assertiontype_t type,
|
|||
isc_assertion_typetotext(type), cond, logsuffix);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
for (i = 0; i < nframes; i++) {
|
||||
#if HAVE_BACKTRACE_SYMBOLS
|
||||
char **strs = backtrace_symbols(tracebuf, nframes);
|
||||
for (int i = 0; i < nframes; i++) {
|
||||
fprintf(stderr, "%s\n", strs[i]);
|
||||
}
|
||||
#else /* HAVE_BACKTRACE_SYMBOLS */
|
||||
for (int i = 0; i < nframes; i++) {
|
||||
fprintf(stderr, "#%d %p in ??\n", i, tracebuf[i]);
|
||||
}
|
||||
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,51 +13,17 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_LIBCTRACE
|
||||
#ifdef HAVE_BACKTRACE
|
||||
#include <execinfo.h>
|
||||
#endif /* ifdef HAVE_LIBCTRACE */
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
|
||||
#include <isc/backtrace.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifdef USE_BACKTRACE
|
||||
/*
|
||||
* Getting a back trace of a running process is tricky and highly platform
|
||||
* dependent. Our current approach is as follows:
|
||||
* 1. If the system library supports the "backtrace()" function, use it.
|
||||
* 2. Otherwise, if the compiler is gcc and the architecture is x86_64 or IA64,
|
||||
* then use gcc's (hidden) Unwind_Backtrace() function. Note that this
|
||||
* function doesn't work for C programs on many other architectures.
|
||||
* 3. Otherwise, if the architecture x86 or x86_64, try to unwind the stack
|
||||
* frame following frame pointers. This assumes the executable binary
|
||||
* compiled with frame pointers; this is not always true for x86_64 (rather,
|
||||
* compiler optimizations often disable frame pointers). The validation
|
||||
* checks in getnextframeptr() hopefully rejects bogus values stored in
|
||||
* the RBP register in such a case. If the backtrace function itself crashes
|
||||
* due to this problem, the whole package should be rebuilt with
|
||||
* --disable-backtrace.
|
||||
*/
|
||||
#ifdef HAVE_LIBCTRACE
|
||||
#define BACKTRACE_LIBC
|
||||
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__ia64__))
|
||||
#define BACKTRACE_GCC
|
||||
#elif defined(WIN32)
|
||||
#define BACKTRACE_WIN32
|
||||
#elif defined(__x86_64__) || defined(__i386__)
|
||||
#define BACKTRACE_X86STACK
|
||||
#else /* ifdef HAVE_LIBCTRACE */
|
||||
#define BACKTRACE_DISABLED
|
||||
#endif /* HAVE_LIBCTRACE */
|
||||
#else /* USE_BACKTRACE */
|
||||
#define BACKTRACE_DISABLED
|
||||
#endif /* USE_BACKTRACE */
|
||||
|
||||
#ifdef BACKTRACE_LIBC
|
||||
#ifdef HAVE_BACKTRACE
|
||||
isc_result_t
|
||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
||||
int n;
|
||||
|
||||
/*
|
||||
* Validate the arguments: intentionally avoid using REQUIRE().
|
||||
* See notes in backtrace.h.
|
||||
|
|
@ -70,154 +36,23 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
|||
* backtrace(3) includes this function itself in the address array,
|
||||
* which should be eliminated from the returned sequence.
|
||||
*/
|
||||
n = backtrace(addrs, maxaddrs);
|
||||
int n = backtrace(addrs, maxaddrs);
|
||||
if (n < 2) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
n--;
|
||||
memmove(addrs, &addrs[1], sizeof(void *) * n);
|
||||
memmove(addrs, &addrs[1], sizeof(addrs[0]) * n);
|
||||
*nframes = n;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(BACKTRACE_GCC)
|
||||
extern int
|
||||
_Unwind_Backtrace(void *fn, void *a);
|
||||
extern void *
|
||||
_Unwind_GetIP(void *ctx);
|
||||
|
||||
typedef struct {
|
||||
void **result;
|
||||
int max_depth;
|
||||
int skip_count;
|
||||
int count;
|
||||
} trace_arg_t;
|
||||
|
||||
static int
|
||||
btcallback(void *uc, void *opq) {
|
||||
trace_arg_t *arg = (trace_arg_t *)opq;
|
||||
|
||||
if (arg->skip_count > 0) {
|
||||
arg->skip_count--;
|
||||
} else {
|
||||
arg->result[arg->count++] = (void *)_Unwind_GetIP(uc);
|
||||
}
|
||||
if (arg->count == arg->max_depth) {
|
||||
return (5); /* _URC_END_OF_STACK */
|
||||
}
|
||||
return (0); /* _URC_NO_REASON */
|
||||
}
|
||||
|
||||
#else /* HAVE_BACKTRACE */
|
||||
isc_result_t
|
||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
||||
trace_arg_t arg;
|
||||
|
||||
/* Argument validation: see above. */
|
||||
if (addrs == NULL || nframes == NULL) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
arg.skip_count = 1;
|
||||
arg.result = addrs;
|
||||
arg.max_depth = maxaddrs;
|
||||
arg.count = 0;
|
||||
_Unwind_Backtrace(btcallback, &arg);
|
||||
|
||||
*nframes = arg.count;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(BACKTRACE_WIN32)
|
||||
isc_result_t
|
||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
||||
unsigned long ftc = (unsigned long)maxaddrs;
|
||||
|
||||
*nframes = (int)CaptureStackBackTrace(1, ftc, addrs, NULL);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(BACKTRACE_X86STACK)
|
||||
#ifdef __x86_64__
|
||||
static unsigned long
|
||||
getrbp(void) {
|
||||
__asm("movq %rbp, %rax\n");
|
||||
}
|
||||
#endif /* ifdef __x86_64__ */
|
||||
|
||||
static void **
|
||||
getnextframeptr(void **sp) {
|
||||
void **newsp = (void **)*sp;
|
||||
|
||||
/*
|
||||
* Perform sanity check for the new frame pointer, derived from
|
||||
* google glog. This can actually be bogus depending on compiler.
|
||||
*/
|
||||
|
||||
/* prohibit the stack frames from growing downwards */
|
||||
if (newsp <= sp) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* A heuristics to reject "too large" frame: this actually happened. */
|
||||
if ((char *)newsp - (char *)sp > 100000) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Not sure if other checks used in glog are needed at this moment.
|
||||
* For our purposes we don't have to consider non-contiguous frames,
|
||||
* for example.
|
||||
*/
|
||||
|
||||
return (newsp);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
||||
int i = 0;
|
||||
void **sp;
|
||||
|
||||
/* Argument validation: see above. */
|
||||
if (addrs == NULL || nframes == NULL) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
sp = (void **)getrbp();
|
||||
if (sp == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
/*
|
||||
* sp is the frame ptr of this function itself due to the call to
|
||||
* getrbp(), so need to unwind one frame for consistency.
|
||||
*/
|
||||
sp = getnextframeptr(sp);
|
||||
#else /* ifdef __x86_64__ */
|
||||
/*
|
||||
* i386: the frame pointer is stored 2 words below the address for the
|
||||
* first argument. Note that the body of this function cannot be
|
||||
* inlined since it depends on the address of the function argument.
|
||||
*/
|
||||
sp = (void **)&addrs - 2;
|
||||
#endif /* ifdef __x86_64__ */
|
||||
|
||||
while (sp != NULL && i < maxaddrs) {
|
||||
addrs[i++] = *(sp + 1);
|
||||
sp = getnextframeptr(sp);
|
||||
}
|
||||
|
||||
*nframes = i;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(BACKTRACE_DISABLED)
|
||||
isc_result_t
|
||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
||||
/* Argument validation: see above. */
|
||||
if (addrs == NULL || nframes == NULL) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
UNUSED(addrs);
|
||||
UNUSED(maxaddrs);
|
||||
UNUSED(nframes);
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
#endif /* ifdef BACKTRACE_LIBC */
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
*** Imports
|
||||
***/
|
||||
|
||||
#if HAVE_BACKTRACE_SYMBOLS
|
||||
#include <execinfo.h>
|
||||
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
||||
|
||||
#include <isc/types.h>
|
||||
|
||||
/***
|
||||
|
|
|
|||
Loading…
Reference in a new issue