mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
Add support for generating backtraces on Windows
This commit adds support for generating backtraces on Windows and refactors the isc_backtrace API to match the Linux/BSD API (without the isc_ prefix) * isc_backtrace_gettrace() was renamed to isc_backtrace(), the third argument was removed and the return type was changed to int * isc_backtrace_symbols() was added * isc_backtrace_symbols_fd() was added and used as appropriate
This commit is contained in:
@@ -205,8 +205,6 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
|
|||||||
const char *cond) {
|
const char *cond) {
|
||||||
void *tracebuf[BACKTRACE_MAXFRAME];
|
void *tracebuf[BACKTRACE_MAXFRAME];
|
||||||
int nframes;
|
int nframes;
|
||||||
isc_result_t result;
|
|
||||||
const char *logsuffix = "";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle assertion failures.
|
* Handle assertion failures.
|
||||||
@@ -219,32 +217,23 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
|
|||||||
*/
|
*/
|
||||||
isc_assertion_setcallback(NULL);
|
isc_assertion_setcallback(NULL);
|
||||||
|
|
||||||
result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME,
|
nframes = isc_backtrace(tracebuf, BACKTRACE_MAXFRAME);
|
||||||
&nframes);
|
|
||||||
if (result == ISC_R_SUCCESS && nframes > 0) {
|
|
||||||
logsuffix = ", back trace";
|
|
||||||
}
|
|
||||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||||
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
|
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
|
||||||
"%s:%d: %s(%s) failed%s", file, line,
|
"%s:%d: %s(%s) failed%s", file, line,
|
||||||
isc_assertion_typetotext(type), cond, logsuffix);
|
isc_assertion_typetotext(type), cond,
|
||||||
if (result == ISC_R_SUCCESS) {
|
(nframes > 0) ? ", back trace" : "");
|
||||||
#if HAVE_BACKTRACE_SYMBOLS
|
if (nframes > 0) {
|
||||||
char **strs = backtrace_symbols(tracebuf, nframes);
|
char **strs = isc_backtrace_symbols(tracebuf, nframes);
|
||||||
for (int i = 0; i < nframes; i++) {
|
if (strs != NULL) {
|
||||||
isc_log_write(named_g_lctx,
|
for (int i = 0; i < nframes; i++) {
|
||||||
NAMED_LOGCATEGORY_GENERAL,
|
isc_log_write(named_g_lctx,
|
||||||
NAMED_LOGMODULE_MAIN,
|
NAMED_LOGCATEGORY_GENERAL,
|
||||||
ISC_LOG_CRITICAL, "%s", strs[i]);
|
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,
|
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||||
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
|
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
|
||||||
|
@@ -975,10 +975,8 @@ AC_SUBST([ZLIB_LIBS])
|
|||||||
# Check if the system supports glibc-compatible backtrace() function.
|
# Check if the system supports glibc-compatible backtrace() function.
|
||||||
#
|
#
|
||||||
AC_CHECK_HEADERS([execinfo.h],
|
AC_CHECK_HEADERS([execinfo.h],
|
||||||
[AC_SEARCH_LIBS([backtrace], [execinfo],
|
[AC_SEARCH_LIBS([backtrace_symbols], [execinfo],
|
||||||
[AC_CHECK_FUNCS([backtrace backtrace_symbols])])])
|
[AC_CHECK_FUNCS([backtrace_symbols])])])
|
||||||
|
|
||||||
AM_CONDITIONAL([HAVE_BACKTRACE], [test "$ac_cv_func_backtrace" = "yes"])
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# We do the IPv6 compilation checking after libtool so that we can put
|
# We do the IPv6 compilation checking after libtool so that we can put
|
||||||
|
@@ -16,8 +16,14 @@
|
|||||||
|
|
||||||
#include <isc/assertions.h>
|
#include <isc/assertions.h>
|
||||||
#include <isc/backtrace.h>
|
#include <isc/backtrace.h>
|
||||||
|
#include <isc/platform.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
|
#include <isc/strerr.h>
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include <dbghelp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The maximum number of stack frames to dump on assertion failure.
|
* The maximum number of stack frames to dump on assertion failure.
|
||||||
@@ -95,30 +101,15 @@ static void
|
|||||||
default_callback(const char *file, int line, isc_assertiontype_t type,
|
default_callback(const char *file, int line, isc_assertiontype_t type,
|
||||||
const char *cond) {
|
const char *cond) {
|
||||||
void *tracebuf[BACKTRACE_MAXFRAME];
|
void *tracebuf[BACKTRACE_MAXFRAME];
|
||||||
int nframes;
|
int nframes = isc_backtrace(tracebuf, BACKTRACE_MAXFRAME);
|
||||||
bool have_backtrace = false;
|
|
||||||
isc_result_t result;
|
|
||||||
|
|
||||||
result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
|
|
||||||
if (result == ISC_R_SUCCESS && nframes > 0) {
|
|
||||||
have_backtrace = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "%s:%d: %s(%s) failed%s\n", file, line,
|
fprintf(stderr, "%s:%d: %s(%s) failed%s\n", file, line,
|
||||||
isc_assertion_typetotext(type), cond,
|
isc_assertion_typetotext(type), cond,
|
||||||
(have_backtrace) ? ", back trace" : ".");
|
(nframes > 0) ? ", back trace" : ".");
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (nframes > 0) {
|
||||||
#if HAVE_BACKTRACE_SYMBOLS
|
isc_backtrace_symbols_fd(tracebuf, nframes, fileno(stderr));
|
||||||
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);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
@@ -13,46 +13,245 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE_SYMBOLS
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#endif /* HAVE_BACKTRACE */
|
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
||||||
|
|
||||||
#include <isc/backtrace.h>
|
#include <isc/backtrace.h>
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/print.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
isc_result_t
|
|
||||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
#include <dbghelp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
isc_backtrace(void **addrs, int maxaddrs, int *nframes) {
|
||||||
|
USHORT n = CaptureStackBackTrace(1, maxaddrs, addrs, NULL);
|
||||||
|
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TRACE_MAX_DEPTH 128
|
||||||
|
#define TRACE_MAX_FUNCTION_NAME_LENGTH 1024
|
||||||
|
|
||||||
|
int
|
||||||
|
vasprintf(char **strp, const char *format, va_list ap) {
|
||||||
|
int len, retval;
|
||||||
|
char *str = NULL;
|
||||||
|
|
||||||
|
len = _vscprintf(format, ap);
|
||||||
|
if (len == -1) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
str = malloc((size_t)len + 1);
|
||||||
|
if (str == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = vsnprintf(str, len + 1, format, ap);
|
||||||
|
if (retval == -1) {
|
||||||
|
free(str);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*strp = str;
|
||||||
|
return (retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
asprintf(char **strp, const char *format, ...) {
|
||||||
|
va_list ap;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
retval = vasprintf(strp, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return (retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
_backtrace_symbols(void *const *buffer, size_t size, bool add_cr) {
|
||||||
|
HANDLE process = GetCurrentProcess();
|
||||||
|
DWORD displacement;
|
||||||
|
uint8_t symbol_storage[sizeof(SYMBOL_INFO) +
|
||||||
|
(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) *
|
||||||
|
sizeof(TCHAR)];
|
||||||
|
SYMBOL_INFO *symbol = (SYMBOL_INFO *)symbol_storage;
|
||||||
|
uint8_t line_storage[sizeof(IMAGEHLP_LINE64)];
|
||||||
|
IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)line_storage;
|
||||||
|
char **lines = NULL;
|
||||||
|
char **outbuf = NULL;
|
||||||
|
char *cur = NULL;
|
||||||
|
size_t outsize = 0;
|
||||||
|
|
||||||
|
if (buffer == NULL || size <= 0) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = malloc(size * sizeof(*lines));
|
||||||
|
if (lines == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize symbol_info */
|
||||||
|
symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
|
||||||
|
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
|
||||||
|
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||||
|
|
||||||
|
SymInitialize(process, NULL, TRUE);
|
||||||
|
|
||||||
|
/* adjust for the char ** array size */
|
||||||
|
outsize = size * sizeof(char *);
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
DWORD64 address = (DWORD64)(buffer[i]);
|
||||||
|
BOOL r;
|
||||||
|
char *file = NULL;
|
||||||
|
unsigned int lineno;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (SymFromAddr(process, address, NULL, symbol) &&
|
||||||
|
SymGetLineFromAddr64(process, address, &displacement, line))
|
||||||
|
{
|
||||||
|
file = line->FileName;
|
||||||
|
lineno = line->LineNumber;
|
||||||
|
} else {
|
||||||
|
file = "??";
|
||||||
|
lineno = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = asprintf(&lines[i], "#%-2d %p in %s at %s:%lu%s", i,
|
||||||
|
(void *)symbol->Address, symbol->Name,
|
||||||
|
line->FileName, line->LineNumber,
|
||||||
|
(add_cr) ? "\n" : "");
|
||||||
|
if (len == -1) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
outsize += strlen(lines[i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
outbuf = malloc(outsize);
|
||||||
|
if (outbuf == NULL) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = (char *)&outbuf[size];
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
size_t remaining = outsize - (cur - (char *)outbuf);
|
||||||
|
size_t copied = strlcpy(cur, lines[i], remaining);
|
||||||
|
if (copied >= remaining) {
|
||||||
|
free(outbuf);
|
||||||
|
outbuf = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
outbuf[i] = cur;
|
||||||
|
cur += copied + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
free(lines[i]);
|
||||||
|
}
|
||||||
|
free(lines);
|
||||||
|
|
||||||
|
return (outbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char **
|
||||||
|
isc_backtrace_symbols(void *const *buffer, int size) {
|
||||||
|
if (buffer == NULL || size <= 0) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (_backtrace_symbols(buffer, size, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_backtrace_symbols_fd(void *const *buffer, int size, int fd) {
|
||||||
|
char **strings = NULL;
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
|
strings = _backtrace_symbols(buffer, size, true);
|
||||||
|
if (strings == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < (size_t)size; i++) {
|
||||||
|
sz = strlen(strings[i]);
|
||||||
|
if (write(fd, strings[i], sz) == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif HAVE_BACKTRACE_SYMBOLS
|
||||||
|
int
|
||||||
|
isc_backtrace(void **addrs, int maxaddrs) {
|
||||||
|
int n;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate the arguments: intentionally avoid using REQUIRE().
|
* Validate the arguments: intentionally avoid using REQUIRE().
|
||||||
* See notes in backtrace.h.
|
* See notes in backtrace.h.
|
||||||
*/
|
*/
|
||||||
if (addrs == NULL || nframes == NULL) {
|
if (addrs == NULL || maxaddrs <= 0) {
|
||||||
return (ISC_R_FAILURE);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* backtrace(3) includes this function itself in the address array,
|
* backtrace(3) includes this function itself in the address array,
|
||||||
* which should be eliminated from the returned sequence.
|
* which should be eliminated from the returned sequence.
|
||||||
*/
|
*/
|
||||||
int n = backtrace(addrs, maxaddrs);
|
n = backtrace(addrs, maxaddrs);
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
return (ISC_R_NOTFOUND);
|
return (-1);
|
||||||
}
|
}
|
||||||
n--;
|
n--;
|
||||||
memmove(addrs, &addrs[1], sizeof(addrs[0]) * n);
|
memmove(addrs, &addrs[1], sizeof(addrs[0]) * n);
|
||||||
*nframes = n;
|
|
||||||
return (ISC_R_SUCCESS);
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_BACKTRACE */
|
char **
|
||||||
isc_result_t
|
isc_backtrace_symbols(void *const *buffer, int size) {
|
||||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
|
return (backtrace_symbols(buffer, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_backtrace_symbols_fd(void *const *buffer, int size, int fd) {
|
||||||
|
backtrace_symbols_fd(buffer, size, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* HAVE_BACKTRACE_SYMBOLS */
|
||||||
|
|
||||||
|
int
|
||||||
|
isc_backtrace(void **addrs, int maxaddrs) {
|
||||||
UNUSED(addrs);
|
UNUSED(addrs);
|
||||||
UNUSED(maxaddrs);
|
UNUSED(maxaddrs);
|
||||||
UNUSED(nframes);
|
|
||||||
|
|
||||||
return (ISC_R_NOTIMPLEMENTED);
|
return (-1);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_BACKTRACE */
|
|
||||||
|
char **
|
||||||
|
isc_backtrace_symbols(void *const *buffer, int size) {
|
||||||
|
UNUSED(buffer);
|
||||||
|
UNUSED(size);
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_backtrace_symbols_fd(void *const *buffer, int size, int fd) {
|
||||||
|
UNUSED(buffer);
|
||||||
|
UNUSED(size);
|
||||||
|
UNUSED(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
||||||
|
@@ -22,25 +22,14 @@
|
|||||||
* dumping a back trace on a fatal error, normally followed by self termination,
|
* dumping a back trace on a fatal error, normally followed by self termination,
|
||||||
* functions defined in this module generally doesn't employ assertion checks
|
* functions defined in this module generally doesn't employ assertion checks
|
||||||
* (if it did, a program bug could cause infinite recursive calls to a
|
* (if it did, a program bug could cause infinite recursive calls to a
|
||||||
* backtrace function). These functions still perform minimal checks and return
|
* backtrace function).
|
||||||
* ISC_R_FAILURE if they detect an error, but the caller should therefore be
|
|
||||||
* very careful about the use of these functions, and generally discouraged to
|
|
||||||
* use them except in an exit path. The exception is
|
|
||||||
* isc_backtrace_getsymbolfromindex(), which is expected to be used in a
|
|
||||||
* non-error-handling context and validates arguments with assertion checks.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ISC_BACKTRACE_H
|
#pragma once
|
||||||
#define ISC_BACKTRACE_H 1
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*** Imports
|
*** Imports
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#if HAVE_BACKTRACE_SYMBOLS
|
|
||||||
#include <execinfo.h>
|
|
||||||
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
|
||||||
|
|
||||||
#include <isc/types.h>
|
#include <isc/types.h>
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -48,8 +37,8 @@
|
|||||||
***/
|
***/
|
||||||
|
|
||||||
ISC_LANG_BEGINDECLS
|
ISC_LANG_BEGINDECLS
|
||||||
isc_result_t
|
int
|
||||||
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
|
isc_backtrace(void **addrs, int maxaddrs);
|
||||||
/*%<
|
/*%<
|
||||||
* Get a back trace of the running process above this function itself. On
|
* Get a back trace of the running process above this function itself. On
|
||||||
* success, addrs[i] will store the address of the call point of the i-th
|
* success, addrs[i] will store the address of the call point of the i-th
|
||||||
@@ -69,6 +58,42 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
|
|||||||
*\li #ISC_R_NOTFOUND
|
*\li #ISC_R_NOTFOUND
|
||||||
*\li #ISC_R_NOTIMPLEMENTED
|
*\li #ISC_R_NOTIMPLEMENTED
|
||||||
*/
|
*/
|
||||||
ISC_LANG_ENDDECLS
|
|
||||||
|
|
||||||
#endif /* ISC_BACKTRACE_H */
|
char **
|
||||||
|
isc_backtrace_symbols(void *const *buffer, int size);
|
||||||
|
/*
|
||||||
|
* isc_backtrace_symbols() attempts to transform a call stack obtained by
|
||||||
|
* backtrace() into an array of human-readable strings using dladdr(). The
|
||||||
|
* array of strings returned has size elements. It is allocated using
|
||||||
|
* malloc() and should be released using free(). There is no need to free
|
||||||
|
* the individual strings in the array.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
*\li On Windows, this is shim implementation using SymFromAddr()
|
||||||
|
*\li On systems with backtrace_symbols(), it's just a thin wrapper
|
||||||
|
*\li Otherwise, it returns NULL
|
||||||
|
*\li See platform NOTES for backtrace_symbols
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
*\li On success, backtrace_symbols() returns a pointer to the array
|
||||||
|
*\li On error, NULL is returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_backtrace_symbols_fd(void *const *buffer, int size, int fd);
|
||||||
|
/*
|
||||||
|
* isc_backtrace_symbols_fd() performs the same operation as
|
||||||
|
* isc_backtrace_symbols(), but the resulting strings are immediately written to
|
||||||
|
* the file descriptor fd, and are not returned. isc_backtrace_symbols_fd()
|
||||||
|
* does not call malloc(3), and so can be employed in situations where the
|
||||||
|
* latter function might fail.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
*\li See isc_backtrace_symbols() notes
|
||||||
|
*\li See platform NOTES for backtrace_symbols_fd for caveats
|
||||||
|
*/
|
||||||
|
|
||||||
|
ISC_LANG_ENDDECLS
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include <isc/atomic.h>
|
#include <isc/atomic.h>
|
||||||
|
#include <isc/backtrace.h>
|
||||||
#include <isc/buffer.h>
|
#include <isc/buffer.h>
|
||||||
#include <isc/condition.h>
|
#include <isc/condition.h>
|
||||||
#include <isc/errno.h>
|
#include <isc/errno.h>
|
||||||
@@ -39,16 +40,6 @@
|
|||||||
#include "openssl_shim.h"
|
#include "openssl_shim.h"
|
||||||
#include "uv-compat.h"
|
#include "uv-compat.h"
|
||||||
|
|
||||||
#if NETMGR_TRACE
|
|
||||||
#if HAVE_BACKTRACE
|
|
||||||
#include <execinfo.h>
|
|
||||||
#else /* HAVE_BACKTRACE */
|
|
||||||
#define backtrace(buffer, size) 0
|
|
||||||
#define backtrace_symbols_fd(buffer, size, fd) \
|
|
||||||
fprintf(stderr, "<not available>");
|
|
||||||
#endif /* HAVE_BACKTRACE */
|
|
||||||
#endif /* NETMGR_TRACE */
|
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* How many isc_nmhandles and isc_nm_uvreqs will we be
|
* How many isc_nmhandles and isc_nm_uvreqs will we be
|
||||||
* caching for reuse in a socket.
|
* caching for reuse in a socket.
|
||||||
@@ -1358,7 +1349,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
|
|||||||
mgr->mctx, ISC_NM_REQS_STACK_SIZE) };
|
mgr->mctx, ISC_NM_REQS_STACK_SIZE) };
|
||||||
|
|
||||||
#if NETMGR_TRACE
|
#if NETMGR_TRACE
|
||||||
sock->backtrace_size = backtrace(sock->backtrace, TRACE_SIZE);
|
sock->backtrace_size = isc_backtrace(sock->backtrace, TRACE_SIZE);
|
||||||
ISC_LINK_INIT(sock, active_link);
|
ISC_LINK_INIT(sock, active_link);
|
||||||
ISC_LIST_INIT(sock->active_handles);
|
ISC_LIST_INIT(sock->active_handles);
|
||||||
LOCK(&mgr->lock);
|
LOCK(&mgr->lock);
|
||||||
@@ -1506,7 +1497,7 @@ isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
|
|||||||
isc___nmsocket_attach(sock, &handle->sock FLARG_PASS);
|
isc___nmsocket_attach(sock, &handle->sock FLARG_PASS);
|
||||||
|
|
||||||
#if NETMGR_TRACE
|
#if NETMGR_TRACE
|
||||||
handle->backtrace_size = backtrace(handle->backtrace, TRACE_SIZE);
|
handle->backtrace_size = isc_backtrace(handle->backtrace, TRACE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (peer != NULL) {
|
if (peer != NULL) {
|
||||||
@@ -3096,8 +3087,8 @@ nmhandle_dump(isc_nmhandle_t *handle) {
|
|||||||
fprintf(stderr, "Active handle %p, refs %" PRIuFAST32 "\n", handle,
|
fprintf(stderr, "Active handle %p, refs %" PRIuFAST32 "\n", handle,
|
||||||
isc_refcount_current(&handle->references));
|
isc_refcount_current(&handle->references));
|
||||||
fprintf(stderr, "Created by:\n");
|
fprintf(stderr, "Created by:\n");
|
||||||
backtrace_symbols_fd(handle->backtrace, handle->backtrace_size,
|
isc_backtrace_symbols_fd(handle->backtrace, handle->backtrace_size,
|
||||||
STDERR_FILENO);
|
STDERR_FILENO);
|
||||||
fprintf(stderr, "\n\n");
|
fprintf(stderr, "\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3121,8 +3112,8 @@ nmsocket_dump(isc_nmsocket_t *sock) {
|
|||||||
atomic_load(&sock->connecting) ? " connecting" : "",
|
atomic_load(&sock->connecting) ? " connecting" : "",
|
||||||
sock->accepting ? " accepting" : "");
|
sock->accepting ? " accepting" : "");
|
||||||
fprintf(stderr, "Created by:\n");
|
fprintf(stderr, "Created by:\n");
|
||||||
backtrace_symbols_fd(sock->backtrace, sock->backtrace_size,
|
isc_backtrace_symbols_fd(sock->backtrace, sock->backtrace_size,
|
||||||
STDERR_FILENO);
|
STDERR_FILENO);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
for (handle = ISC_LIST_HEAD(sock->active_handles); handle != NULL;
|
for (handle = ISC_LIST_HEAD(sock->active_handles); handle != NULL;
|
||||||
|
@@ -131,7 +131,9 @@ isc_appctx_destroy
|
|||||||
isc_assertion_failed
|
isc_assertion_failed
|
||||||
isc_assertion_setcallback
|
isc_assertion_setcallback
|
||||||
isc_assertion_typetotext
|
isc_assertion_typetotext
|
||||||
isc_backtrace_gettrace
|
isc_backtrace
|
||||||
|
isc_backtrace_symbols
|
||||||
|
isc_backtrace_symbols_fd
|
||||||
isc_base32_decoderegion
|
isc_base32_decoderegion
|
||||||
isc_base32_decodestring
|
isc_base32_decodestring
|
||||||
isc_base32_tobuffer
|
isc_base32_tobuffer
|
||||||
|
@@ -80,7 +80,7 @@
|
|||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
|
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
|
||||||
<AdditionalDependencies>@OPENSSL_LIBCRYPTO@@OPENSSL_LIBSSL@@LIBUV_LIB@@NGHTTP2_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>@OPENSSL_LIBCRYPTO@@OPENSSL_LIBSSL@@LIBUV_LIB@@NGHTTP2_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;Dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ModuleDefinitionFile>$(ProjectName).def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>$(ProjectName).def</ModuleDefinitionFile>
|
||||||
<ImportLibrary>.\$(Configuration)\$(ProjectName).lib</ImportLibrary>
|
<ImportLibrary>.\$(Configuration)\$(ProjectName).lib</ImportLibrary>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -168,7 +168,7 @@ copy InstallFiles ..\Build\Debug\
|
|||||||
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
|
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
|
||||||
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
@ELSE PKCS11
|
@ELSE PKCS11
|
||||||
<PreprocessorDefinitions>BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>BIND9;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
|
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
|
||||||
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
@END PKCS11
|
@END PKCS11
|
||||||
|
Reference in New Issue
Block a user