mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Merge remote-tracking branch 'tor-github/pr/1379'
This commit is contained in:
commit
58b87a2c59
3
changes/bug31734
Normal file
3
changes/bug31734
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
o Minor bugfixes (error handling):
|
||||||
|
- Always lock the backtrace buffer before it is used.
|
||||||
|
Fixes bug 31734; bugfix on 0.2.5.3-alpha.
|
@ -52,9 +52,10 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "lib/cc/ctassert.h"
|
||||||
|
|
||||||
#define EXPOSE_CLEAN_BACKTRACE
|
#define EXPOSE_CLEAN_BACKTRACE
|
||||||
#include "lib/err/backtrace.h"
|
#include "lib/err/backtrace.h"
|
||||||
#include "lib/err/torerr.h"
|
|
||||||
|
|
||||||
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
|
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
|
||||||
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) && \
|
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) && \
|
||||||
@ -73,15 +74,40 @@
|
|||||||
static char bt_version[128] = "";
|
static char bt_version[128] = "";
|
||||||
|
|
||||||
#ifdef USE_BACKTRACE
|
#ifdef USE_BACKTRACE
|
||||||
|
|
||||||
/** Largest stack depth to try to dump. */
|
/** Largest stack depth to try to dump. */
|
||||||
#define MAX_DEPTH 256
|
#define MAX_DEPTH 256
|
||||||
/** Static allocation of stack to dump. This is static so we avoid stack
|
/** The size of the callback buffer, so we can clear it in unlock_cb_buf(). */
|
||||||
* pressure. */
|
#define SIZEOF_CB_BUF (MAX_DEPTH * sizeof(void *))
|
||||||
static void *cb_buf[MAX_DEPTH];
|
|
||||||
/** Protects cb_buf from concurrent access. Pthreads, since this code
|
/** Protects cb_buf from concurrent access. Pthreads, since this code
|
||||||
* is Unix-only, and since this code needs to be lowest-level. */
|
* is Unix-only, and since this code needs to be lowest-level. */
|
||||||
static pthread_mutex_t cb_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t cb_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/** Lock and return a static stack pointer buffer that can hold up to
|
||||||
|
* MAX_DEPTH function pointers. */
|
||||||
|
static void *
|
||||||
|
lock_cb_buf(void)
|
||||||
|
{
|
||||||
|
/* Lock the mutex first, before even declaring the buffer. */
|
||||||
|
pthread_mutex_lock(&cb_buf_mutex);
|
||||||
|
|
||||||
|
/** Static allocation of stack to dump. This is static so we avoid stack
|
||||||
|
* pressure. */
|
||||||
|
static void *cb_buf[MAX_DEPTH];
|
||||||
|
CTASSERT(SIZEOF_CB_BUF == sizeof(cb_buf));
|
||||||
|
memset(cb_buf, 0, SIZEOF_CB_BUF);
|
||||||
|
|
||||||
|
return cb_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unlock the static stack pointer buffer. */
|
||||||
|
static void
|
||||||
|
unlock_cb_buf(void *cb_buf)
|
||||||
|
{
|
||||||
|
memset(cb_buf, 0, SIZEOF_CB_BUF);
|
||||||
|
pthread_mutex_unlock(&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
|
||||||
* <b>ctx</b>. (When we get a signal, the current function will not have
|
* <b>ctx</b>. (When we get a signal, the current function will not have
|
||||||
@ -123,7 +149,7 @@ log_backtrace_impl(int severity, log_domain_mask_t domain, const char *msg,
|
|||||||
char **symbols;
|
char **symbols;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
pthread_mutex_lock(&cb_buf_mutex);
|
void *cb_buf = lock_cb_buf();
|
||||||
|
|
||||||
depth = backtrace(cb_buf, MAX_DEPTH);
|
depth = backtrace(cb_buf, MAX_DEPTH);
|
||||||
symbols = backtrace_symbols(cb_buf, (int)depth);
|
symbols = backtrace_symbols(cb_buf, (int)depth);
|
||||||
@ -141,7 +167,7 @@ log_backtrace_impl(int severity, log_domain_mask_t domain, const char *msg,
|
|||||||
raw_free(symbols);
|
raw_free(symbols);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
pthread_mutex_unlock(&cb_buf_mutex);
|
unlock_cb_buf(cb_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void crash_handler(int sig, siginfo_t *si, void *ctx_)
|
static void crash_handler(int sig, siginfo_t *si, void *ctx_)
|
||||||
@ -157,6 +183,8 @@ crash_handler(int sig, siginfo_t *si, void *ctx_)
|
|||||||
int n_fds, i;
|
int n_fds, i;
|
||||||
const int *fds = NULL;
|
const int *fds = NULL;
|
||||||
|
|
||||||
|
void *cb_buf = lock_cb_buf();
|
||||||
|
|
||||||
(void) si;
|
(void) si;
|
||||||
|
|
||||||
depth = backtrace(cb_buf, MAX_DEPTH);
|
depth = backtrace(cb_buf, MAX_DEPTH);
|
||||||
@ -173,6 +201,8 @@ crash_handler(int sig, siginfo_t *si, void *ctx_)
|
|||||||
for (i=0; i < n_fds; ++i)
|
for (i=0; i < n_fds; ++i)
|
||||||
backtrace_symbols_fd(cb_buf, (int)depth, fds[i]);
|
backtrace_symbols_fd(cb_buf, (int)depth, fds[i]);
|
||||||
|
|
||||||
|
unlock_cb_buf(cb_buf);
|
||||||
|
|
||||||
tor_raw_abort_();
|
tor_raw_abort_();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,11 +214,15 @@ dump_stack_symbols_to_error_fds(void)
|
|||||||
const int *fds = NULL;
|
const int *fds = NULL;
|
||||||
size_t depth;
|
size_t depth;
|
||||||
|
|
||||||
|
void *cb_buf = lock_cb_buf();
|
||||||
|
|
||||||
depth = backtrace(cb_buf, MAX_DEPTH);
|
depth = backtrace(cb_buf, MAX_DEPTH);
|
||||||
|
|
||||||
n_fds = tor_log_get_sigsafe_err_fds(&fds);
|
n_fds = tor_log_get_sigsafe_err_fds(&fds);
|
||||||
for (i=0; i < n_fds; ++i)
|
for (i=0; i < n_fds; ++i)
|
||||||
backtrace_symbols_fd(cb_buf, (int)depth, fds[i]);
|
backtrace_symbols_fd(cb_buf, (int)depth, fds[i]);
|
||||||
|
|
||||||
|
unlock_cb_buf(cb_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The signals that we want our backtrace handler to trap */
|
/* The signals that we want our backtrace handler to trap */
|
||||||
@ -222,10 +256,12 @@ install_bt_handler(void)
|
|||||||
* libc has pre-loaded the symbols we need to dump things, so that later
|
* libc has pre-loaded the symbols we need to dump things, so that later
|
||||||
* reads won't be denied by the sandbox code */
|
* reads won't be denied by the sandbox code */
|
||||||
char **symbols;
|
char **symbols;
|
||||||
|
void *cb_buf = lock_cb_buf();
|
||||||
size_t depth = backtrace(cb_buf, MAX_DEPTH);
|
size_t depth = backtrace(cb_buf, MAX_DEPTH);
|
||||||
symbols = backtrace_symbols(cb_buf, (int) depth);
|
symbols = backtrace_symbols(cb_buf, (int) depth);
|
||||||
if (symbols)
|
if (symbols)
|
||||||
raw_free(symbols);
|
raw_free(symbols);
|
||||||
|
unlock_cb_buf(cb_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
Loading…
Reference in New Issue
Block a user