mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-19 18:00:33 +01:00
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".
This commit is contained in:
parent
1753975ece
commit
a3ab31f5dc
8
changes/bug11048
Normal file
8
changes/bug11048
Normal file
@ -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.
|
@ -49,6 +49,8 @@ static char *bt_version = NULL;
|
|||||||
/** Static allocation of stack to dump. This is static so we avoid stack
|
/** Static allocation of stack to dump. This is static so we avoid stack
|
||||||
* pressure. */
|
* pressure. */
|
||||||
static void *cb_buf[MAX_DEPTH];
|
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
|
/** 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
|
* 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
|
void
|
||||||
log_backtrace(int severity, int domain, const char *msg)
|
log_backtrace(int severity, int domain, const char *msg)
|
||||||
{
|
{
|
||||||
int depth = backtrace(cb_buf, MAX_DEPTH);
|
int depth;
|
||||||
char **symbols = backtrace_symbols(cb_buf, depth);
|
char **symbols;
|
||||||
int i;
|
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);
|
tor_log(severity, domain, "%s. Stack trace:", msg);
|
||||||
if (!symbols) {
|
if (!symbols) {
|
||||||
tor_log(severity, domain, " Unable to generate backtrace.");
|
tor_log(severity, domain, " Unable to generate backtrace.");
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
for (i=0; i < depth; ++i) {
|
for (i=0; i < depth; ++i) {
|
||||||
tor_log(severity, domain, " %s", symbols[i]);
|
tor_log(severity, domain, " %s", symbols[i]);
|
||||||
}
|
}
|
||||||
free(symbols);
|
free(symbols);
|
||||||
|
|
||||||
|
done:
|
||||||
|
tor_mutex_release(&cb_buf_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void crash_handler(int sig, siginfo_t *si, void *ctx_)
|
static void crash_handler(int sig, siginfo_t *si, void *ctx_)
|
||||||
@ -140,6 +151,9 @@ install_bt_handler(void)
|
|||||||
int i, rv=0;
|
int i, rv=0;
|
||||||
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
|
tor_mutex_init(&cb_buf_mutex);
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sa_sigaction = crash_handler;
|
sa.sa_sigaction = crash_handler;
|
||||||
sa.sa_flags = SA_SIGINFO;
|
sa.sa_flags = SA_SIGINFO;
|
||||||
@ -158,7 +172,7 @@ install_bt_handler(void)
|
|||||||
static void
|
static void
|
||||||
remove_bt_handler(void)
|
remove_bt_handler(void)
|
||||||
{
|
{
|
||||||
/* We don't need to actually free anything at exit here. */
|
tor_mutex_uninit(&cb_buf_mutex);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user