Ticket #11048: 0001-Threadproof-our-log_backtrace-implementation.patch

File 0001-Threadproof-our-log_backtrace-implementation.patch, 2.9 KB (added by nickm, 7 years ago)
  • new file changes/bug11048

    From a3ab31f5dc55b2edde9436f6fb5f990548950702 Mon Sep 17 00:00:00 2001
    From: Nick Mathewson <nickm@torproject.org>
    Date: Mon, 24 Feb 2014 12:15:32 -0500
    Subject: [PATCH] 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".
    ---
     changes/bug11048       |  8 ++++++++
     src/common/backtrace.c | 22 ++++++++++++++++++----
     2 files changed, 26 insertions(+), 4 deletions(-)
     create mode 100644 changes/bug11048
    
    diff --git a/changes/bug11048 b/changes/bug11048
    new file mode 100644
    index 0000000..684abf9
    - +  
     1  o Minor bugfixes:
     2
     3    - Avoid strange behavior if two threads hit failed asswertions
     4      at the same time and both try to log backtraces at
     5      once. (Previously, if this had happened, both threads would
     6      have stored their intermediate results in the same buffer, and
     7      generated junk outputs.) Reported by "cypherpunks". Fixes bug
     8      11048; bugfix on 0.2.5.2-alpha.
  • src/common/backtrace.c

    diff --git a/src/common/backtrace.c b/src/common/backtrace.c
    index 5049298..3db2d6c 100644
    a b static char *bt_version = NULL; 
    4949/** Static allocation of stack to dump. This is static so we avoid stack
    5050 * pressure. */
    5151static void *cb_buf[MAX_DEPTH];
     52/** Protects cb_buf_mutex from concurrent access */
     53static tor_mutex_t cb_buf_mutex;
    5254
    5355/** Change a stacktrace in <b>stack</b> of depth <b>depth</b> so that it will
    5456 * log the correct function from which a signal was received with context
    clean_backtrace(void **stack, int depth, const ucontext_t *ctx) 
    8486void
    8587log_backtrace(int severity, int domain, const char *msg)
    8688{
    87   int depth = backtrace(cb_buf, MAX_DEPTH);
    88   char **symbols = backtrace_symbols(cb_buf, depth);
     89  int depth;
     90  char **symbols;
    8991  int i;
     92
     93  tor_mutex_acquire(&cb_buf_mutex);
     94
     95  depth = backtrace(cb_buf, MAX_DEPTH);
     96  symbols = backtrace_symbols(cb_buf, depth);
     97
    9098  tor_log(severity, domain, "%s. Stack trace:", msg);
    9199  if (!symbols) {
    92100    tor_log(severity, domain, "    Unable to generate backtrace.");
    93     return;
     101    goto done;
    94102  }
    95103  for (i=0; i < depth; ++i) {
    96104    tor_log(severity, domain, "    %s", symbols[i]);
    97105  }
    98106  free(symbols);
     107
     108 done:
     109  tor_mutex_release(&cb_buf_mutex);
    99110}
    100111
    101112static void crash_handler(int sig, siginfo_t *si, void *ctx_)
    install_bt_handler(void) 
    140151  int i, rv=0;
    141152
    142153  struct sigaction sa;
     154
     155  tor_mutex_init(&cb_buf_mutex);
     156
    143157  memset(&sa, 0, sizeof(sa));
    144158  sa.sa_sigaction = crash_handler;
    145159  sa.sa_flags = SA_SIGINFO;
    install_bt_handler(void) 
    158172static void
    159173remove_bt_handler(void)
    160174{
    161   /* We don't need to actually free anything at exit here. */
     175  tor_mutex_uninit(&cb_buf_mutex);
    162176}
    163177#endif
    164178