2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

2667. [func] Add support for logging stack backtrace on assertion

failure (not available for all platforms). [RT #19780]
9.7.0
This commit is contained in:
Tatuya JINMEI 神明達哉
2009-09-01 18:40:25 +00:00
parent 11254f9c5a
commit a27fe4c990
22 changed files with 946 additions and 69 deletions

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: main.c,v 1.172 2009/05/07 09:33:52 fdupont Exp $ */
/* $Id: main.c,v 1.173 2009/09/01 18:40:25 jinmei Exp $ */
/*! \file */
@@ -26,6 +26,7 @@
#include <string.h>
#include <isc/app.h>
#include <isc/backtrace.h>
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/entropy.h>
@@ -81,6 +82,13 @@
#include <dlz/dlz_drivers.h>
#endif
/*
* The maximum number of stack frames to dump on assertion failure.
*/
#ifndef BACKTRACE_MAXFRAME
#define BACKTRACE_MAXFRAME 128
#endif
static isc_boolean_t want_stats = ISC_FALSE;
static char program_name[ISC_DIR_NAMEMAX] = "named";
static char absolute_conffile[ISC_DIR_PATHMAX];
@@ -134,6 +142,12 @@ static void
assertion_failed(const char *file, int line, isc_assertiontype_t type,
const char *cond)
{
void *tracebuf[BACKTRACE_MAXFRAME];
int i, nframes;
isc_result_t result;
const char *logsuffix = "";
const char *fname;
/*
* Handle assertion failures.
*/
@@ -145,10 +159,40 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
*/
isc_assertion_setcallback(NULL);
result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME,
&nframes);
if (result == ISC_R_SUCCESS && nframes > 0)
logsuffix = ", back trace";
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
"%s:%d: %s(%s) failed", file, line,
isc_assertion_typetotext(type), cond);
"%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++) {
unsigned long offset;
fname = NULL;
result = isc_backtrace_getsymbol(tracebuf[i],
&fname,
&offset);
if (result == ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"#%d %p in %s()+0x%lx", i,
tracebuf[i], fname,
offset);
} else {
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"#%d %p in ??", i,
tracebuf[i]);
}
}
}
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
"exiting (due to assertion failure)");
@@ -584,6 +628,34 @@ destroy_managers(void) {
isc_hash_destroy();
}
static void
dump_symboltable() {
int i;
isc_result_t result;
const char *fname;
const void *addr;
if (isc__backtrace_nsymbols == 0)
return;
if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(99)))
return;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
ISC_LOG_DEBUG(99), "Symbol table:");
for (i = 0, result = ISC_R_SUCCESS; result == ISC_R_SUCCESS; i++) {
addr = NULL;
fname = NULL;
result = isc_backtrace_getsymbolfromindex(i, &addr, &fname);
if (result == ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(99),
"[%d] %p %s", i, addr, fname);
}
}
}
static void
setup(void) {
isc_result_t result;
@@ -691,6 +763,8 @@ setup(void) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
ISC_LOG_NOTICE, "built with %s", ns_g_configargs);
dump_symboltable();
/*
* Get the initial resource limits.
*/
@@ -902,6 +976,9 @@ main(int argc, char *argv[]) {
if (strcmp(program_name, "lwresd") == 0)
ns_g_lwresdonly = ISC_TRUE;
if (result != ISC_R_SUCCESS)
ns_main_earlyfatal("failed to build internal symbol table");
isc_assertion_setcallback(assertion_failed);
isc_error_setfatal(library_fatal_error);
isc_error_setunexpected(library_unexpected_error);