Home | History | Annotate | Download | only in sanitizer_common
      1 //===-- sanitizer_stoptheworld_linux.cc -----------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // See sanitizer_stoptheworld.h for details.
     11 // This implementation was inspired by Markus Gutschke's linuxthreads.cc.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifdef __linux__
     16 
     17 #include "sanitizer_stoptheworld.h"
     18 
     19 #include <errno.h>
     20 #include <sched.h> // for clone
     21 #include <stddef.h>
     22 #include <sys/prctl.h> // for PR_* definitions
     23 #include <sys/ptrace.h> // for PTRACE_* definitions
     24 #include <sys/types.h> // for pid_t
     25 #include <sys/wait.h> // for signal-related stuff
     26 
     27 #include "sanitizer_common.h"
     28 #include "sanitizer_libc.h"
     29 #include "sanitizer_linux.h"
     30 #include "sanitizer_mutex.h"
     31 #include "sanitizer_placement_new.h"
     32 
     33 // This module works by spawning a Linux task which then attaches to every
     34 // thread in the caller process with ptrace. This suspends the threads, and
     35 // PTRACE_GETREGS can then be used to obtain their register state. The callback
     36 // supplied to StopTheWorld() is run in the tracer task while the threads are
     37 // suspended.
     38 // The tracer task must be placed in a different thread group for ptrace to
     39 // work, so it cannot be spawned as a pthread. Instead, we use the low-level
     40 // clone() interface (we want to share the address space with the caller
     41 // process, so we prefer clone() over fork()).
     42 //
     43 // We avoid the use of libc for two reasons:
     44 // 1. calling a library function while threads are suspended could cause a
     45 // deadlock, if one of the treads happens to be holding a libc lock;
     46 // 2. it's generally not safe to call libc functions from the tracer task,
     47 // because clone() does not set up a thread-local storage for it. Any
     48 // thread-local variables used by libc will be shared between the tracer task
     49 // and the thread which spawned it.
     50 //
     51 // We deal with this by replacing libc calls with calls to our own
     52 // implementations defined in sanitizer_libc.h and sanitizer_linux.h. However,
     53 // there are still some libc functions which are used here:
     54 //
     55 // * All of the system calls ultimately go through the libc syscall() function.
     56 // We're operating under the assumption that syscall()'s implementation does
     57 // not acquire any locks or use any thread-local data (except for the errno
     58 // variable, which we handle separately).
     59 //
     60 // * We lack custom implementations of sigfillset() and sigaction(), so we use
     61 // the libc versions instead. The same assumptions as above apply.
     62 //
     63 // * It is safe to call libc functions before the cloned thread is spawned or
     64 // after it has exited. The following functions are used in this manner:
     65 // sigdelset()
     66 // sigprocmask()
     67 // clone()
     68 
     69 COMPILER_CHECK(sizeof(SuspendedThreadID) == sizeof(pid_t));
     70 
     71 namespace __sanitizer {
     72 // This class handles thread suspending/unsuspending in the tracer thread.
     73 class ThreadSuspender {
     74  public:
     75   explicit ThreadSuspender(pid_t pid)
     76     : pid_(pid) {
     77       CHECK_GE(pid, 0);
     78     }
     79   bool SuspendAllThreads();
     80   void ResumeAllThreads();
     81   void KillAllThreads();
     82   SuspendedThreadsList &suspended_threads_list() {
     83     return suspended_threads_list_;
     84   }
     85  private:
     86   SuspendedThreadsList suspended_threads_list_;
     87   pid_t pid_;
     88   bool SuspendThread(SuspendedThreadID thread_id);
     89 };
     90 
     91 bool ThreadSuspender::SuspendThread(SuspendedThreadID thread_id) {
     92   // Are we already attached to this thread?
     93   // Currently this check takes linear time, however the number of threads is
     94   // usually small.
     95   if (suspended_threads_list_.Contains(thread_id))
     96     return false;
     97   if (internal_ptrace(PTRACE_ATTACH, thread_id, NULL, NULL) != 0) {
     98     // Either the thread is dead, or something prevented us from attaching.
     99     // Log this event and move on.
    100     Report("Could not attach to thread %d (errno %d).\n", thread_id, errno);
    101     return false;
    102   } else {
    103     if (SanitizerVerbosity > 0)
    104       Report("Attached to thread %d.\n", thread_id);
    105     // The thread is not guaranteed to stop before ptrace returns, so we must
    106     // wait on it.
    107     int waitpid_status;
    108     HANDLE_EINTR(waitpid_status, internal_waitpid(thread_id, NULL, __WALL));
    109     if (waitpid_status < 0) {
    110       // Got a ECHILD error. I don't think this situation is possible, but it
    111       // doesn't hurt to report it.
    112       Report("Waiting on thread %d failed, detaching (errno %d).\n", thread_id,
    113              errno);
    114       internal_ptrace(PTRACE_DETACH, thread_id, NULL, NULL);
    115       return false;
    116     }
    117     suspended_threads_list_.Append(thread_id);
    118     return true;
    119   }
    120 }
    121 
    122 void ThreadSuspender::ResumeAllThreads() {
    123   for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++) {
    124     pid_t tid = suspended_threads_list_.GetThreadID(i);
    125     if (internal_ptrace(PTRACE_DETACH, tid, NULL, NULL) == 0) {
    126       if (SanitizerVerbosity > 0)
    127         Report("Detached from thread %d.\n", tid);
    128     } else {
    129       // Either the thread is dead, or we are already detached.
    130       // The latter case is possible, for instance, if this function was called
    131       // from a signal handler.
    132       Report("Could not detach from thread %d (errno %d).\n", tid, errno);
    133     }
    134   }
    135 }
    136 
    137 void ThreadSuspender::KillAllThreads() {
    138   for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++)
    139     internal_ptrace(PTRACE_KILL, suspended_threads_list_.GetThreadID(i),
    140                     NULL, NULL);
    141 }
    142 
    143 bool ThreadSuspender::SuspendAllThreads() {
    144   void *mem = InternalAlloc(sizeof(ThreadLister));
    145   ThreadLister *thread_lister = new(mem) ThreadLister(pid_);
    146   bool added_threads;
    147   do {
    148     // Run through the directory entries once.
    149     added_threads = false;
    150     pid_t tid = thread_lister->GetNextTID();
    151     while (tid >= 0) {
    152       if (SuspendThread(tid))
    153         added_threads = true;
    154       tid = thread_lister->GetNextTID();
    155     }
    156     if (thread_lister->error()) {
    157       // Detach threads and fail.
    158       ResumeAllThreads();
    159       InternalFree(mem);
    160       return false;
    161     }
    162     thread_lister->Reset();
    163   } while (added_threads);
    164   InternalFree(mem);
    165   return true;
    166 }
    167 
    168 // Pointer to the ThreadSuspender instance for use in signal handler.
    169 static ThreadSuspender *thread_suspender_instance = NULL;
    170 
    171 // Signals that should not be blocked (this is used in the parent thread as well
    172 // as the tracer thread).
    173 static const int kUnblockedSignals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV,
    174                                          SIGBUS, SIGXCPU, SIGXFSZ };
    175 
    176 // Structure for passing arguments into the tracer thread.
    177 struct TracerThreadArgument {
    178   StopTheWorldCallback callback;
    179   void *callback_argument;
    180   // The tracer thread waits on this mutex while the parent finished its
    181   // preparations.
    182   BlockingMutex mutex;
    183 };
    184 
    185 // Signal handler to wake up suspended threads when the tracer thread dies.
    186 void TracerThreadSignalHandler(int signum, siginfo_t *siginfo, void *) {
    187   if (thread_suspender_instance != NULL) {
    188     if (signum == SIGABRT)
    189       thread_suspender_instance->KillAllThreads();
    190     else
    191       thread_suspender_instance->ResumeAllThreads();
    192   }
    193   internal__exit((signum == SIGABRT) ? 1 : 2);
    194 }
    195 
    196 // Size of alternative stack for signal handlers in the tracer thread.
    197 static const int kHandlerStackSize = 4096;
    198 
    199 // This function will be run as a cloned task.
    200 static int TracerThread(void* argument) {
    201   TracerThreadArgument *tracer_thread_argument =
    202       (TracerThreadArgument *)argument;
    203 
    204   // Wait for the parent thread to finish preparations.
    205   tracer_thread_argument->mutex.Lock();
    206   tracer_thread_argument->mutex.Unlock();
    207 
    208   ThreadSuspender thread_suspender(internal_getppid());
    209   // Global pointer for the signal handler.
    210   thread_suspender_instance = &thread_suspender;
    211 
    212   // Alternate stack for signal handling.
    213   InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize);
    214   struct sigaltstack handler_stack;
    215   internal_memset(&handler_stack, 0, sizeof(handler_stack));
    216   handler_stack.ss_sp = handler_stack_memory.data();
    217   handler_stack.ss_size = kHandlerStackSize;
    218   internal_sigaltstack(&handler_stack, NULL);
    219 
    220   // Install our handler for fatal signals. Other signals should be blocked by
    221   // the mask we inherited from the caller thread.
    222   for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals);
    223        signal_index++) {
    224     struct sigaction new_sigaction;
    225     internal_memset(&new_sigaction, 0, sizeof(new_sigaction));
    226     new_sigaction.sa_sigaction = TracerThreadSignalHandler;
    227     new_sigaction.sa_flags = SA_ONSTACK | SA_SIGINFO;
    228     sigfillset(&new_sigaction.sa_mask);
    229     sigaction(kUnblockedSignals[signal_index], &new_sigaction, NULL);
    230   }
    231 
    232   int exit_code = 0;
    233   if (!thread_suspender.SuspendAllThreads()) {
    234     Report("Failed suspending threads.\n");
    235     exit_code = 3;
    236   } else {
    237     tracer_thread_argument->callback(thread_suspender.suspended_threads_list(),
    238                                      tracer_thread_argument->callback_argument);
    239     thread_suspender.ResumeAllThreads();
    240     exit_code = 0;
    241   }
    242   thread_suspender_instance = NULL;
    243   handler_stack.ss_flags = SS_DISABLE;
    244   internal_sigaltstack(&handler_stack, NULL);
    245   return exit_code;
    246 }
    247 
    248 static sigset_t blocked_sigset;
    249 static sigset_t old_sigset;
    250 static struct sigaction old_sigactions[ARRAY_SIZE(kUnblockedSignals)];
    251 
    252 void StopTheWorld(StopTheWorldCallback callback, void *argument) {
    253   // Block all signals that can be blocked safely, and install default handlers
    254   // for the remaining signals.
    255   // We cannot allow user-defined handlers to run while the ThreadSuspender
    256   // thread is active, because they could conceivably call some libc functions
    257   // which modify errno (which is shared between the two threads).
    258   sigfillset(&blocked_sigset);
    259   for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals);
    260        signal_index++) {
    261     // Remove the signal from the set of blocked signals.
    262     sigdelset(&blocked_sigset, kUnblockedSignals[signal_index]);
    263     // Install the default handler.
    264     struct sigaction new_sigaction;
    265     internal_memset(&new_sigaction, 0, sizeof(new_sigaction));
    266     new_sigaction.sa_handler = SIG_DFL;
    267     sigfillset(&new_sigaction.sa_mask);
    268     sigaction(kUnblockedSignals[signal_index], &new_sigaction,
    269                     &old_sigactions[signal_index]);
    270   }
    271   int sigprocmask_status = sigprocmask(SIG_BLOCK, &blocked_sigset, &old_sigset);
    272   CHECK_EQ(sigprocmask_status, 0); // sigprocmask should never fail
    273   // Make this process dumpable. Processes that are not dumpable cannot be
    274   // attached to.
    275   int process_was_dumpable = internal_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
    276   if (!process_was_dumpable)
    277     internal_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
    278   // Prepare the arguments for TracerThread.
    279   struct TracerThreadArgument tracer_thread_argument;
    280   tracer_thread_argument.callback = callback;
    281   tracer_thread_argument.callback_argument = argument;
    282   // Block the execution of TracerThread until after we have set ptrace
    283   // permissions.
    284   tracer_thread_argument.mutex.Lock();
    285   // The tracer thread will run on the same stack, so we must reserve some
    286   // stack space for the caller thread to run in as it waits on the tracer.
    287   const uptr kReservedStackSize = 4096;
    288   // Get a 16-byte aligned pointer for stack.
    289   int a_local_variable __attribute__((__aligned__(16)));
    290   pid_t tracer_pid = clone(TracerThread,
    291                           (char *)&a_local_variable - kReservedStackSize,
    292                           CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED,
    293                           &tracer_thread_argument, 0, 0, 0);
    294   if (tracer_pid < 0) {
    295     Report("Failed spawning a tracer thread (errno %d).\n", errno);
    296     tracer_thread_argument.mutex.Unlock();
    297   } else {
    298     // On some systems we have to explicitly declare that we want to be traced
    299     // by the tracer thread.
    300 #ifdef PR_SET_PTRACER
    301     internal_prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0);
    302 #endif
    303     // Allow the tracer thread to start.
    304     tracer_thread_argument.mutex.Unlock();
    305     // Since errno is shared between this thread and the tracer thread, we
    306     // must avoid using errno while the tracer thread is running.
    307     // At this point, any signal will either be blocked or kill us, so waitpid
    308     // should never return (and set errno) while the tracer thread is alive.
    309     int waitpid_status = internal_waitpid(tracer_pid, NULL, __WALL);
    310     if (waitpid_status < 0)
    311       Report("Waiting on the tracer thread failed (errno %d).\n", errno);
    312   }
    313   // Restore the dumpable flag.
    314   if (!process_was_dumpable)
    315     internal_prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
    316   // Restore the signal handlers.
    317   for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals);
    318        signal_index++) {
    319     sigaction(kUnblockedSignals[signal_index],
    320               &old_sigactions[signal_index], NULL);
    321   }
    322   sigprocmask(SIG_SETMASK, &old_sigset, &old_sigset);
    323 }
    324 
    325 }  // namespace __sanitizer
    326 
    327 #endif  // __linux__
    328