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