backtrace.c (9496B)
1 /* Copyright (c) 2013-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * \file backtrace.c 6 * 7 * \brief Functions to produce backtraces on bugs, crashes, or assertion 8 * failures. 9 * 10 * Currently, we've only got an implementation here using the backtrace() 11 * family of functions, which are sometimes provided by libc and sometimes 12 * provided by libexecinfo. We tie into the sigaction() backend in order to 13 * detect crashes. 14 * 15 * This is one of the lowest-level modules, since nearly everything needs to 16 * be able to log an error. As such, it doesn't call the log module or any 17 * other higher-level modules directly. 18 */ 19 20 #include "orconfig.h" 21 #include "lib/err/torerr.h" 22 23 #ifdef HAVE_EXECINFO_H 24 #include <execinfo.h> 25 #endif 26 #ifdef HAVE_FCNTL_H 27 #include <fcntl.h> 28 #endif 29 #ifdef HAVE_UNISTD_H 30 #include <unistd.h> 31 #endif 32 #ifdef HAVE_SIGNAL_H 33 #include <signal.h> 34 #endif 35 #ifdef HAVE_SYS_PARAM_H 36 #include <sys/param.h> 37 #endif 38 #include <errno.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <stdio.h> 42 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) 48 #include <ucontext.h> 49 #endif /* defined(HAVE_CYGWIN_SIGNAL_H) || ... */ 50 51 #ifdef HAVE_PTHREAD_H 52 #include <pthread.h> 53 #endif 54 55 #include "lib/cc/ctassert.h" 56 57 #define BACKTRACE_PRIVATE 58 #include "lib/err/backtrace.h" 59 60 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ 61 defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) && \ 62 defined(HAVE_PTHREAD_H) 63 #define USE_BACKTRACE 64 #endif 65 66 #if !defined(USE_BACKTRACE) 67 #define NO_BACKTRACE_IMPL 68 #endif 69 70 // Redundant with util.h, but doing it here so we can avoid that dependency. 71 #define raw_free free 72 73 /** Version of Tor to report in backtrace messages. */ 74 static char bt_version[128] = ""; 75 76 #ifdef USE_BACKTRACE 77 78 /** Largest stack depth to try to dump. */ 79 #define MAX_DEPTH 256 80 /** The size of the callback buffer, so we can clear it in unlock_cb_buf(). */ 81 #define SIZEOF_CB_BUF (MAX_DEPTH * sizeof(void *)) 82 /** Protects cb_buf from concurrent access. Pthreads, since this code 83 * is Unix-only, and since this code needs to be lowest-level. */ 84 static pthread_mutex_t cb_buf_mutex = PTHREAD_MUTEX_INITIALIZER; 85 86 /** Lock and return a static stack pointer buffer that can hold up to 87 * MAX_DEPTH function pointers. */ 88 static void ** 89 lock_cb_buf(void) 90 { 91 /* Lock the mutex first, before even declaring the buffer. */ 92 pthread_mutex_lock(&cb_buf_mutex); 93 94 /** Static allocation of stack to dump. This is static so we avoid stack 95 * pressure. */ 96 static void *cb_buf[MAX_DEPTH]; 97 CTASSERT(SIZEOF_CB_BUF == sizeof(cb_buf)); 98 memset(cb_buf, 0, SIZEOF_CB_BUF); 99 100 return cb_buf; 101 } 102 103 /** Unlock the static stack pointer buffer. */ 104 static void 105 unlock_cb_buf(void **cb_buf) 106 { 107 memset(cb_buf, 0, SIZEOF_CB_BUF); 108 pthread_mutex_unlock(&cb_buf_mutex); 109 } 110 111 /** Change a stacktrace in <b>stack</b> of depth <b>depth</b> so that it will 112 * log the correct function from which a signal was received with context 113 * <b>ctx</b>. (When we get a signal, the current function will not have 114 * called any other function, and will therefore have not pushed its address 115 * onto the stack. Fortunately, we usually have the program counter in the 116 * ucontext_t structure. 117 */ 118 void 119 clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx) 120 { 121 #ifdef PC_FROM_UCONTEXT 122 #if defined(__linux__) 123 const size_t n = 1; 124 #elif defined(__darwin__) || defined(__APPLE__) || defined(OpenBSD) \ 125 || defined(__FreeBSD__) 126 const size_t n = 2; 127 #else 128 const size_t n = 1; 129 #endif /* defined(__linux__) || ... */ 130 if (depth <= n) 131 return; 132 133 stack[n] = (void*) ctx->PC_FROM_UCONTEXT; 134 #else /* !defined(PC_FROM_UCONTEXT) */ 135 (void) depth; 136 (void) ctx; 137 (void) stack; 138 #endif /* defined(PC_FROM_UCONTEXT) */ 139 } 140 141 /** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow 142 * that with a backtrace log. Send messages via the tor_log function at 143 * logger". */ 144 void 145 log_backtrace_impl(int severity, log_domain_mask_t domain, const char *msg, 146 tor_log_fn logger) 147 { 148 size_t depth; 149 char **symbols; 150 size_t i; 151 152 void **cb_buf = lock_cb_buf(); 153 154 depth = backtrace(cb_buf, MAX_DEPTH); 155 symbols = backtrace_symbols(cb_buf, (int)depth); 156 157 logger(severity, domain, "%s: %s. Stack trace:", bt_version, msg); 158 if (!symbols) { 159 /* LCOV_EXCL_START -- we can't provoke this. */ 160 logger(severity, domain, " Unable to generate backtrace."); 161 goto done; 162 /* LCOV_EXCL_STOP */ 163 } 164 for (i=0; i < depth; ++i) { 165 logger(severity, domain, " %s", symbols[i]); 166 } 167 raw_free(symbols); 168 169 done: 170 unlock_cb_buf(cb_buf); 171 } 172 173 static void crash_handler(int sig, siginfo_t *si, void *ctx_) 174 __attribute__((noreturn)); 175 176 /** Signal handler: write a crash message with a stack trace, and die. */ 177 static void 178 crash_handler(int sig, siginfo_t *si, void *ctx_) 179 { 180 char buf[40]; 181 size_t depth; 182 ucontext_t *ctx = (ucontext_t *) ctx_; 183 int n_fds, i; 184 const int *fds = NULL; 185 186 void **cb_buf = lock_cb_buf(); 187 188 (void) si; 189 190 depth = backtrace(cb_buf, MAX_DEPTH); 191 /* Clean up the top stack frame so we get the real function 192 * name for the most recently failing function. */ 193 clean_backtrace(cb_buf, depth, ctx); 194 195 format_dec_number_sigsafe((unsigned)sig, buf, sizeof(buf)); 196 197 tor_log_err_sigsafe(bt_version, " died: Caught signal ", buf, "\n", 198 NULL); 199 200 n_fds = tor_log_get_sigsafe_err_fds(&fds); 201 for (i=0; i < n_fds; ++i) 202 backtrace_symbols_fd(cb_buf, (int)depth, fds[i]); 203 204 unlock_cb_buf(cb_buf); 205 206 tor_raw_abort_(); 207 } 208 209 /** Write a backtrace to all of the emergency-error fds. */ 210 void 211 dump_stack_symbols_to_error_fds(void) 212 { 213 int n_fds, i; 214 const int *fds = NULL; 215 size_t depth; 216 217 void **cb_buf = lock_cb_buf(); 218 219 depth = backtrace(cb_buf, MAX_DEPTH); 220 221 n_fds = tor_log_get_sigsafe_err_fds(&fds); 222 for (i=0; i < n_fds; ++i) 223 backtrace_symbols_fd(cb_buf, (int)depth, fds[i]); 224 225 unlock_cb_buf(cb_buf); 226 } 227 228 /* The signals that we want our backtrace handler to trap */ 229 static int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, 230 SIGIO, -1 }; 231 232 /** Install signal handlers as needed so that when we crash, we produce a 233 * useful stack trace. Return 0 on success, -errno on failure. */ 234 static int 235 install_bt_handler(void) 236 { 237 int i, rv=0; 238 239 struct sigaction sa; 240 241 memset(&sa, 0, sizeof(sa)); 242 sa.sa_sigaction = crash_handler; 243 sa.sa_flags = SA_SIGINFO; 244 sigfillset(&sa.sa_mask); 245 246 for (i = 0; trap_signals[i] >= 0; ++i) { 247 if (sigaction(trap_signals[i], &sa, NULL) == -1) { 248 /* LCOV_EXCL_START */ 249 rv = -errno; 250 /* LCOV_EXCL_STOP */ 251 } 252 } 253 254 { 255 /* Now, generate (but do not log) a backtrace. This ensures that 256 * libc has pre-loaded the symbols we need to dump things, so that later 257 * reads won't be denied by the sandbox code */ 258 char **symbols; 259 void **cb_buf = lock_cb_buf(); 260 size_t depth = backtrace(cb_buf, MAX_DEPTH); 261 symbols = backtrace_symbols(cb_buf, (int) depth); 262 if (symbols) 263 raw_free(symbols); 264 unlock_cb_buf(cb_buf); 265 } 266 267 return rv; 268 } 269 270 /** Uninstall crash handlers. */ 271 static void 272 remove_bt_handler(void) 273 { 274 int i; 275 276 struct sigaction sa; 277 278 memset(&sa, 0, sizeof(sa)); 279 sa.sa_handler = SIG_DFL; 280 sigfillset(&sa.sa_mask); 281 282 for (i = 0; trap_signals[i] >= 0; ++i) { 283 /* remove_bt_handler() is called on shutdown, from low-level code. 284 * It's not a fatal error, so we just ignore it. */ 285 (void)sigaction(trap_signals[i], &sa, NULL); 286 } 287 288 /* cb_buf_mutex is statically initialised, so we can not destroy it. 289 * If we destroy it, and then re-initialise tor, all our backtraces will 290 * fail. */ 291 } 292 #endif /* defined(USE_BACKTRACE) */ 293 294 #ifdef NO_BACKTRACE_IMPL 295 void 296 log_backtrace_impl(int severity, log_domain_mask_t domain, const char *msg, 297 tor_log_fn logger) 298 { 299 logger(severity, domain, "%s: %s. (Stack trace not available)", 300 bt_version, msg); 301 } 302 303 static int 304 install_bt_handler(void) 305 { 306 return 0; 307 } 308 309 static void 310 remove_bt_handler(void) 311 { 312 } 313 314 void 315 dump_stack_symbols_to_error_fds(void) 316 { 317 } 318 #endif /* defined(NO_BACKTRACE_IMPL) */ 319 320 /** Return the tor version used for error messages on crashes. 321 * Signal-safe: returns a pointer to a static array. */ 322 const char * 323 get_tor_backtrace_version(void) 324 { 325 return bt_version; 326 } 327 328 /** Set up code to handle generating error messages on crashes. */ 329 int 330 configure_backtrace_handler(const char *tor_version) 331 { 332 char version[128] = "Tor\0"; 333 334 if (tor_version) { 335 int snp_rv = 0; 336 /* We can't use strlcat() here, because it is defined in 337 * string/compat_string.h on some platforms, and string uses torerr. */ 338 snp_rv = snprintf(version, sizeof(version), "Tor %s", tor_version); 339 /* It's safe to call raw_assert() here, because raw_assert() does not 340 * call configure_backtrace_handler(). */ 341 raw_assert(snp_rv < (int)sizeof(version)); 342 raw_assert(snp_rv >= 0); 343 } 344 345 char *str_rv = NULL; 346 /* We can't use strlcpy() here, see the note about strlcat() above. */ 347 str_rv = strncpy(bt_version, version, sizeof(bt_version) - 1); 348 /* We must terminate bt_version, then raw_assert(), because raw_assert() 349 * uses bt_version. */ 350 bt_version[sizeof(bt_version) - 1] = 0; 351 raw_assert(str_rv == bt_version); 352 353 return install_bt_handler(); 354 } 355 356 /** Perform end-of-process cleanup for code that generates error messages on 357 * crashes. */ 358 void 359 clean_up_backtrace_handler(void) 360 { 361 remove_bt_handler(); 362 }