aboutsummaryrefslogtreecommitdiff
path: root/src/common/backtrace.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-04-10 15:44:52 -0400
committerNick Mathewson <nickm@torproject.org>2014-04-10 15:44:52 -0400
commitcc9e86db61e2ffb6c54b09e8c41e8fdad50b3ef3 (patch)
tree14a025fd59522d8c2baac100764d8a664756b587 /src/common/backtrace.c
parent196895ed7ed1bd4c93c4c3cdd12893cfa4e4cc41 (diff)
downloadtor-cc9e86db61e2ffb6c54b09e8c41e8fdad50b3ef3.tar
tor-cc9e86db61e2ffb6c54b09e8c41e8fdad50b3ef3.tar.gz
Log a backtrace when the sandbox finds a failure
This involves some duplicate code between backtrace.c and sandbox.c, but I don't see a way around it: calling more functions would mean adding more steps to our call stack, and running clean_backtrace() against the wrong point on the stack.
Diffstat (limited to 'src/common/backtrace.c')
-rw-r--r--src/common/backtrace.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/common/backtrace.c b/src/common/backtrace.c
index 239c65782..3a073a8ff 100644
--- a/src/common/backtrace.c
+++ b/src/common/backtrace.c
@@ -5,7 +5,6 @@
#define _GNU_SOURCE 1
#include "orconfig.h"
-#include "backtrace.h"
#include "compat.h"
#include "util.h"
#include "torlog.h"
@@ -31,6 +30,9 @@
#include <ucontext.h>
#endif
+#define EXPOSE_CLEAN_BACKTRACE
+#include "backtrace.h"
+
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
#define USE_BACKTRACE
@@ -59,7 +61,7 @@ static tor_mutex_t cb_buf_mutex;
* onto the stack. Fortunately, we usually have the program counter in the
* ucontext_t structure.
*/
-static void
+void
clean_backtrace(void **stack, int depth, const ucontext_t *ctx)
{
#ifdef PC_FROM_UCONTEXT
@@ -165,6 +167,18 @@ install_bt_handler(void)
rv = -1;
}
}
+
+ {
+ /* Now, generate (but do not log) a backtrace. This ensures that
+ * libc has pre-loaded the symbols we need to dump things, so that later
+ * reads won't be denied by the sandbox code */
+ char **symbols;
+ int depth = backtrace(cb_buf, MAX_DEPTH);
+ symbols = backtrace_symbols(cb_buf, depth);
+ if (symbols)
+ free(symbols);
+ }
+
return rv;
}