2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-27 20:49:04 +00:00
bind/lib/isc/backtrace.c
Tony Finch 295e7c80e8 Ad-hoc backtrace logging with isc_backtrace_log()
It's sometimes helpful to get a quick idea of the call stack when
debugging. This change factors out the backtrace logging from named's
fatal error handler so that it's easy to use in other places too.
2023-03-29 10:47:53 +00:00

119 lines
2.4 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_BACKTRACE_SYMBOLS
#include <execinfo.h>
#endif /* HAVE_BACKTRACE_SYMBOLS */
#include <isc/backtrace.h>
#include <isc/log.h>
#include <isc/result.h>
#include <isc/util.h>
#if HAVE_BACKTRACE_SYMBOLS
int
isc_backtrace(void **addrs, int maxaddrs) {
int n;
/*
* Validate the arguments: intentionally avoid using REQUIRE().
* See notes in backtrace.h.
*/
if (addrs == NULL || maxaddrs <= 0) {
return (-1);
}
/*
* backtrace(3) includes this function itself in the address array,
* which should be eliminated from the returned sequence.
*/
n = backtrace(addrs, maxaddrs);
if (n < 2) {
return (-1);
}
n--;
memmove(addrs, &addrs[1], sizeof(addrs[0]) * n);
return (n);
}
char **
isc_backtrace_symbols(void *const *buffer, int size) {
return (backtrace_symbols(buffer, size));
}
void
isc_backtrace_symbols_fd(void *const *buffer, int size, int fd) {
backtrace_symbols_fd(buffer, size, fd);
}
void
isc_backtrace_log(isc_log_t *lctx, isc_logcategory_t *category,
isc_logmodule_t *module, int level) {
void *tracebuf[ISC_BACKTRACE_MAXFRAME];
int nframes;
char **strs;
nframes = isc_backtrace(tracebuf, ISC_BACKTRACE_MAXFRAME);
if (nframes <= 0) {
return;
}
strs = isc_backtrace_symbols(tracebuf, nframes);
if (strs == NULL) {
return;
}
for (int i = 0; i < nframes; i++) {
isc_log_write(lctx, category, module, level, "%s", strs[i]);
}
}
#else /* HAVE_BACKTRACE_SYMBOLS */
int
isc_backtrace(void **addrs, int maxaddrs) {
UNUSED(addrs);
UNUSED(maxaddrs);
return (-1);
}
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);
}
void
isc_backtrace_log(isc_log_t *lctx, isc_logcategory_t *category,
isc_logmodule_t *module, int level) {
UNUSED(lctx);
UNUSED(category);
UNUSED(module);
UNUSED(level);
}
#endif /* HAVE_BACKTRACE_SYMBOLS */