aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-02-24 12:15:32 -0500
committerNick Mathewson <nickm@torproject.org>2014-02-24 12:15:32 -0500
commita3ab31f5dc55b2edde9436f6fb5f990548950702 (patch)
tree472e1cc0365d66386162cee47393f27ba3555b71
parent1753975ece98f4054ec65683862db120a3b8f261 (diff)
downloadtor-a3ab31f5dc55b2edde9436f6fb5f990548950702.tar
tor-a3ab31f5dc55b2edde9436f6fb5f990548950702.tar.gz
Threadproof our log_backtrace implementation
It's possible for two threads to hit assertion failures at the same time. If that happens, let's keep them from stomping on the same cb_buf field. Fixes bug 11048; bugfix on 0.2.5.2-alpha. Reported by "cypherpunks".
-rw-r--r--changes/bug110488
-rw-r--r--src/common/backtrace.c22
2 files changed, 26 insertions, 4 deletions
diff --git a/changes/bug11048 b/changes/bug11048
new file mode 100644
index 000000000..684abf959
--- /dev/null
+++ b/changes/bug11048
@@ -0,0 +1,8 @@
+ o Minor bugfixes:
+
+ - Avoid strange behavior if two threads hit failed asswertions
+ at the same time and both try to log backtraces at
+ once. (Previously, if this had happened, both threads would
+ have stored their intermediate results in the same buffer, and
+ generated junk outputs.) Reported by "cypherpunks". Fixes bug
+ 11048; bugfix on 0.2.5.2-alpha.
diff --git a/src/common/backtrace.c b/src/common/backtrace.c
index 5049298a1..3db2d6c23 100644
--- a/src/common/backtrace.c
+++ b/src/common/backtrace.c
@@ -49,6 +49,8 @@ static char *bt_version = NULL;
/** Static allocation of stack to dump. This is static so we avoid stack
* pressure. */
static void *cb_buf[MAX_DEPTH];
+/** Protects cb_buf_mutex from concurrent access */
+static tor_mutex_t cb_buf_mutex;
/** Change a stacktrace in <b>stack</b> of depth <b>depth</b> so that it will
* log the correct function from which a signal was received with context
@@ -84,18 +86,27 @@ clean_backtrace(void **stack, int depth, const ucontext_t *ctx)
void
log_backtrace(int severity, int domain, const char *msg)
{
- int depth = backtrace(cb_buf, MAX_DEPTH);
- char **symbols = backtrace_symbols(cb_buf, depth);
+ int depth;
+ char **symbols;
int i;
+
+ tor_mutex_acquire(&cb_buf_mutex);
+
+ depth = backtrace(cb_buf, MAX_DEPTH);
+ symbols = backtrace_symbols(cb_buf, depth);
+
tor_log(severity, domain, "%s. Stack trace:", msg);
if (!symbols) {
tor_log(severity, domain, " Unable to generate backtrace.");
- return;
+ goto done;
}
for (i=0; i < depth; ++i) {
tor_log(severity, domain, " %s", symbols[i]);
}
free(symbols);
+
+ done:
+ tor_mutex_release(&cb_buf_mutex);
}
static void crash_handler(int sig, siginfo_t *si, void *ctx_)
@@ -140,6 +151,9 @@ install_bt_handler(void)
int i, rv=0;
struct sigaction sa;
+
+ tor_mutex_init(&cb_buf_mutex);
+
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = crash_handler;
sa.sa_flags = SA_SIGINFO;
@@ -158,7 +172,7 @@ install_bt_handler(void)
static void
remove_bt_handler(void)
{
- /* We don't need to actually free anything at exit here. */
+ tor_mutex_uninit(&cb_buf_mutex);
}
#endif