Tor  0.4.7.0-alpha-dev
backtrace.c
Go to the documentation of this file.
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 *
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
360 {
361  remove_bt_handler();
362 }
static char bt_version[128]
Definition: backtrace.c:74
int configure_backtrace_handler(const char *tor_version)
Definition: backtrace.c:330
const char * get_tor_backtrace_version(void)
Definition: backtrace.c:323
void clean_up_backtrace_handler(void)
Definition: backtrace.c:359
Header for backtrace.c.
Compile-time assertions: CTASSERT(expression).
#define CTASSERT(x)
Definition: ctassert.h:44
uint64_t log_domain_mask_t
Definition: logging_types.h:21
int format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
Definition: torerr.c:305
void tor_log_err_sigsafe(const char *m,...)
Definition: torerr.c:70
void tor_raw_abort_(void)
Definition: torerr.c:222
int tor_log_get_sigsafe_err_fds(const int **out)
Definition: torerr.c:103
Headers for torerr.c.