35#ifdef HAVE_SYS_PARAM_H
43#ifdef HAVE_CYGWIN_SIGNAL_H
44#include <cygwin/signal.h>
45#elif defined(HAVE_SYS_UCONTEXT_H)
46#include <sys/ucontext.h>
47#elif defined(HAVE_UCONTEXT_H)
57#define BACKTRACE_PRIVATE
60#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
61 defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) && \
62 defined(HAVE_PTHREAD_H)
66#if !defined(USE_BACKTRACE)
67#define NO_BACKTRACE_IMPL
81#define SIZEOF_CB_BUF (MAX_DEPTH * sizeof(void *))
84static pthread_mutex_t cb_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
92 pthread_mutex_lock(&cb_buf_mutex);
96 static void *cb_buf[MAX_DEPTH];
97 CTASSERT(SIZEOF_CB_BUF ==
sizeof(cb_buf));
98 memset(cb_buf, 0, SIZEOF_CB_BUF);
105unlock_cb_buf(
void **cb_buf)
107 memset(cb_buf, 0, SIZEOF_CB_BUF);
108 pthread_mutex_unlock(&cb_buf_mutex);
119clean_backtrace(
void **stack,
size_t depth,
const ucontext_t *ctx)
121#ifdef PC_FROM_UCONTEXT
122#if defined(__linux__)
124#elif defined(__darwin__) || defined(__APPLE__) || defined(OpenBSD) \
125 || defined(__FreeBSD__)
133 stack[n] = (
void*) ctx->PC_FROM_UCONTEXT;
152 void **cb_buf = lock_cb_buf();
154 depth = backtrace(cb_buf, MAX_DEPTH);
155 symbols = backtrace_symbols(cb_buf, (
int)depth);
157 logger(severity, domain,
"%s: %s. Stack trace:",
bt_version, msg);
160 logger(severity, domain,
" Unable to generate backtrace.");
164 for (i=0; i < depth; ++i) {
165 logger(severity, domain,
" %s", symbols[i]);
170 unlock_cb_buf(cb_buf);
173static void crash_handler(
int sig, siginfo_t *si,
void *ctx_)
174 __attribute__((noreturn));
178crash_handler(
int sig, siginfo_t *si,
void *ctx_)
182 ucontext_t *ctx = (ucontext_t *) ctx_;
184 const int *fds = NULL;
186 void **cb_buf = lock_cb_buf();
190 depth = backtrace(cb_buf, MAX_DEPTH);
193 clean_backtrace(cb_buf, depth, ctx);
201 for (i=0; i < n_fds; ++i)
202 backtrace_symbols_fd(cb_buf, (
int)depth, fds[i]);
204 unlock_cb_buf(cb_buf);
211dump_stack_symbols_to_error_fds(
void)
214 const int *fds = NULL;
217 void **cb_buf = lock_cb_buf();
219 depth = backtrace(cb_buf, MAX_DEPTH);
222 for (i=0; i < n_fds; ++i)
223 backtrace_symbols_fd(cb_buf, (
int)depth, fds[i]);
225 unlock_cb_buf(cb_buf);
229static int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS,
235install_bt_handler(
void)
241 memset(&sa, 0,
sizeof(sa));
242 sa.sa_sigaction = crash_handler;
243 sa.sa_flags = SA_SIGINFO;
244 sigfillset(&sa.sa_mask);
246 for (i = 0; trap_signals[i] >= 0; ++i) {
247 if (sigaction(trap_signals[i], &sa, NULL) == -1) {
259 void **cb_buf = lock_cb_buf();
260 size_t depth = backtrace(cb_buf, MAX_DEPTH);
261 symbols = backtrace_symbols(cb_buf, (
int) depth);
264 unlock_cb_buf(cb_buf);
272remove_bt_handler(
void)
278 memset(&sa, 0,
sizeof(sa));
279 sa.sa_handler = SIG_DFL;
280 sigfillset(&sa.sa_mask);
282 for (i = 0; trap_signals[i] >= 0; ++i) {
285 (void)sigaction(trap_signals[i], &sa, NULL);
294#ifdef NO_BACKTRACE_IMPL
299 logger(severity, domain,
"%s: %s. (Stack trace not available)",
304install_bt_handler(
void)
310remove_bt_handler(
void)
315dump_stack_symbols_to_error_fds(
void)
332 char version[128] =
"Tor\0";
338 snp_rv = snprintf(version,
sizeof(version),
"Tor %s", tor_version);
341 raw_assert(snp_rv < (
int)
sizeof(version));
342 raw_assert(snp_rv >= 0);
353 return install_bt_handler();
static char bt_version[128]
const char * get_tor_backtrace_version(void)
int configure_backtrace_handler(const char *tor_version)
void clean_up_backtrace_handler(void)
Compile-time assertions: CTASSERT(expression).
CTASSERT(NUMBER_SECOND_GUARDS< 20)
uint64_t log_domain_mask_t
int format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
void tor_log_err_sigsafe(const char *m,...)
void tor_raw_abort_(void)
int tor_log_get_sigsafe_err_fds(const int **out)