23 #ifdef HAVE_EXECINFO_H
35 #ifdef HAVE_SYS_PARAM_H
36 #include <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 *))
84 static 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);
105 unlock_cb_buf(
void **cb_buf)
107 memset(cb_buf, 0, SIZEOF_CB_BUF);
108 pthread_mutex_unlock(&cb_buf_mutex);
119 clean_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);
173 static void crash_handler(
int sig, siginfo_t *si,
void *ctx_)
174 __attribute__((noreturn));
178 crash_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);
211 dump_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);
229 static int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS,
235 install_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);
272 remove_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)",
304 install_bt_handler(
void)
310 remove_bt_handler(
void)
315 dump_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]
int configure_backtrace_handler(const char *tor_version)
const char * get_tor_backtrace_version(void)
void clean_up_backtrace_handler(void)
Compile-time assertions: CTASSERT(expression).
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)