1 //===-- sanitizer_stoptheworld_linux_libcdep.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 16 #include "sanitizer_platform.h" 17 #if SANITIZER_LINUX && defined(__x86_64__) 18 19 #include "sanitizer_stoptheworld.h" 20 21 #include "sanitizer_platform_limits_posix.h" 22 23 #include <errno.h> 24 #include <sched.h> // for CLONE_* definitions 25 #include <stddef.h> 26 #include <sys/prctl.h> // for PR_* definitions 27 #include <sys/ptrace.h> // for PTRACE_* definitions 28 #include <sys/types.h> // for pid_t 29 #if SANITIZER_ANDROID && defined(__arm__) 30 # include <linux/user.h> // for pt_regs 31 #else 32 # include <sys/user.h> // for user_regs_struct 33 #endif 34 #include <sys/wait.h> // for signal-related stuff 35 36 #ifdef sa_handler 37 # undef sa_handler 38 #endif 39 40 #ifdef sa_sigaction 41 # undef sa_sigaction 42 #endif 43 44 #include "sanitizer_common.h" 45 #include "sanitizer_flags.h" 46 #include "sanitizer_libc.h" 47 #include "sanitizer_linux.h" 48 #include "sanitizer_mutex.h" 49 #include "sanitizer_placement_new.h" 50 51 // This module works by spawning a Linux task which then attaches to every 52 // thread in the caller process with ptrace. This suspends the threads, and 53 // PTRACE_GETREGS can then be used to obtain their register state. The callback 54 // supplied to StopTheWorld() is run in the tracer task while the threads are 55 // suspended. 56 // The tracer task must be placed in a different thread group for ptrace to 57 // work, so it cannot be spawned as a pthread. Instead, we use the low-level 58 // clone() interface (we want to share the address space with the caller 59 // process, so we prefer clone() over fork()). 60 // 61 // We don't use any libc functions, relying instead on direct syscalls. There 62 // are two reasons for this: 63 // 1. calling a library function while threads are suspended could cause a 64 // deadlock, if one of the treads happens to be holding a libc lock; 65 // 2. it's generally not safe to call libc functions from the tracer task, 66 // because clone() does not set up a thread-local storage for it. Any 67 // thread-local variables used by libc will be shared between the tracer task 68 // and the thread which spawned it. 69 70 COMPILER_CHECK(sizeof(SuspendedThreadID) == sizeof(pid_t)); 71 72 namespace __sanitizer { 73 // This class handles thread suspending/unsuspending in the tracer thread. 74 class ThreadSuspender { 75 public: 76 explicit ThreadSuspender(pid_t pid) 77 : pid_(pid) { 78 CHECK_GE(pid, 0); 79 } 80 bool SuspendAllThreads(); 81 void ResumeAllThreads(); 82 void KillAllThreads(); 83 SuspendedThreadsList &suspended_threads_list() { 84 return suspended_threads_list_; 85 } 86 private: 87 SuspendedThreadsList suspended_threads_list_; 88 pid_t pid_; 89 bool SuspendThread(SuspendedThreadID thread_id); 90 }; 91 92 bool ThreadSuspender::SuspendThread(SuspendedThreadID thread_id) { 93 // Are we already attached to this thread? 94 // Currently this check takes linear time, however the number of threads is 95 // usually small. 96 if (suspended_threads_list_.Contains(thread_id)) 97 return false; 98 int pterrno; 99 if (internal_iserror(internal_ptrace(PTRACE_ATTACH, thread_id, NULL, NULL), 100 &pterrno)) { 101 // Either the thread is dead, or something prevented us from attaching. 102 // Log this event and move on. 103 VReport(1, "Could not attach to thread %d (errno %d).\n", thread_id, 104 pterrno); 105 return false; 106 } else { 107 VReport(1, "Attached to thread %d.\n", thread_id); 108 // The thread is not guaranteed to stop before ptrace returns, so we must 109 // wait on it. 110 uptr waitpid_status; 111 HANDLE_EINTR(waitpid_status, internal_waitpid(thread_id, NULL, __WALL)); 112 int wperrno; 113 if (internal_iserror(waitpid_status, &wperrno)) { 114 // Got a ECHILD error. I don't think this situation is possible, but it 115 // doesn't hurt to report it. 116 VReport(1, "Waiting on thread %d failed, detaching (errno %d).\n", 117 thread_id, wperrno); 118 internal_ptrace(PTRACE_DETACH, thread_id, NULL, NULL); 119 return false; 120 } 121 suspended_threads_list_.Append(thread_id); 122 return true; 123 } 124 } 125 126 void ThreadSuspender::ResumeAllThreads() { 127 for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++) { 128 pid_t tid = suspended_threads_list_.GetThreadID(i); 129 int pterrno; 130 if (!internal_iserror(internal_ptrace(PTRACE_DETACH, tid, NULL, NULL), 131 &pterrno)) { 132 VReport(1, "Detached from thread %d.\n", tid); 133 } else { 134 // Either the thread is dead, or we are already detached. 135 // The latter case is possible, for instance, if this function was called 136 // from a signal handler. 137 VReport(1, "Could not detach from thread %d (errno %d).\n", tid, pterrno); 138 } 139 } 140 } 141 142 void ThreadSuspender::KillAllThreads() { 143 for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++) 144 internal_ptrace(PTRACE_KILL, suspended_threads_list_.GetThreadID(i), 145 NULL, NULL); 146 } 147 148 bool ThreadSuspender::SuspendAllThreads() { 149 ThreadLister thread_lister(pid_); 150 bool added_threads; 151 do { 152 // Run through the directory entries once. 153 added_threads = false; 154 pid_t tid = thread_lister.GetNextTID(); 155 while (tid >= 0) { 156 if (SuspendThread(tid)) 157 added_threads = true; 158 tid = thread_lister.GetNextTID(); 159 } 160 if (thread_lister.error()) { 161 // Detach threads and fail. 162 ResumeAllThreads(); 163 return false; 164 } 165 thread_lister.Reset(); 166 } while (added_threads); 167 return true; 168 } 169 170 // Pointer to the ThreadSuspender instance for use in signal handler. 171 static ThreadSuspender *thread_suspender_instance = NULL; 172 173 // Signals that should not be blocked (this is used in the parent thread as well 174 // as the tracer thread). 175 static const int kUnblockedSignals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, 176 SIGBUS, SIGXCPU, SIGXFSZ }; 177 178 // Structure for passing arguments into the tracer thread. 179 struct TracerThreadArgument { 180 StopTheWorldCallback callback; 181 void *callback_argument; 182 // The tracer thread waits on this mutex while the parent finishes its 183 // preparations. 184 BlockingMutex mutex; 185 uptr parent_pid; 186 }; 187 188 static DieCallbackType old_die_callback; 189 190 // Signal handler to wake up suspended threads when the tracer thread dies. 191 void TracerThreadSignalHandler(int signum, void *siginfo, void *) { 192 if (thread_suspender_instance != NULL) { 193 if (signum == SIGABRT) 194 thread_suspender_instance->KillAllThreads(); 195 else 196 thread_suspender_instance->ResumeAllThreads(); 197 } 198 internal__exit((signum == SIGABRT) ? 1 : 2); 199 } 200 201 static void TracerThreadDieCallback() { 202 // Generally a call to Die() in the tracer thread should be fatal to the 203 // parent process as well, because they share the address space. 204 // This really only works correctly if all the threads are suspended at this 205 // point. So we correctly handle calls to Die() from within the callback, but 206 // not those that happen before or after the callback. Hopefully there aren't 207 // a lot of opportunities for that to happen... 208 if (thread_suspender_instance) 209 thread_suspender_instance->KillAllThreads(); 210 if (old_die_callback) 211 old_die_callback(); 212 } 213 214 // Size of alternative stack for signal handlers in the tracer thread. 215 static const int kHandlerStackSize = 4096; 216 217 // This function will be run as a cloned task. 218 static int TracerThread(void* argument) { 219 TracerThreadArgument *tracer_thread_argument = 220 (TracerThreadArgument *)argument; 221 222 internal_prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 223 // Check if parent is already dead. 224 if (internal_getppid() != tracer_thread_argument->parent_pid) 225 internal__exit(4); 226 227 // Wait for the parent thread to finish preparations. 228 tracer_thread_argument->mutex.Lock(); 229 tracer_thread_argument->mutex.Unlock(); 230 231 SetDieCallback(TracerThreadDieCallback); 232 233 ThreadSuspender thread_suspender(internal_getppid()); 234 // Global pointer for the signal handler. 235 thread_suspender_instance = &thread_suspender; 236 237 // Alternate stack for signal handling. 238 InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize); 239 struct sigaltstack handler_stack; 240 internal_memset(&handler_stack, 0, sizeof(handler_stack)); 241 handler_stack.ss_sp = handler_stack_memory.data(); 242 handler_stack.ss_size = kHandlerStackSize; 243 internal_sigaltstack(&handler_stack, NULL); 244 245 // Install our handler for fatal signals. Other signals should be blocked by 246 // the mask we inherited from the caller thread. 247 for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); 248 signal_index++) { 249 __sanitizer_sigaction new_sigaction; 250 internal_memset(&new_sigaction, 0, sizeof(new_sigaction)); 251 new_sigaction.sigaction = TracerThreadSignalHandler; 252 new_sigaction.sa_flags = SA_ONSTACK | SA_SIGINFO; 253 internal_sigfillset(&new_sigaction.sa_mask); 254 internal_sigaction_norestorer(kUnblockedSignals[signal_index], 255 &new_sigaction, NULL); 256 } 257 258 int exit_code = 0; 259 if (!thread_suspender.SuspendAllThreads()) { 260 VReport(1, "Failed suspending threads.\n"); 261 exit_code = 3; 262 } else { 263 tracer_thread_argument->callback(thread_suspender.suspended_threads_list(), 264 tracer_thread_argument->callback_argument); 265 thread_suspender.ResumeAllThreads(); 266 exit_code = 0; 267 } 268 thread_suspender_instance = NULL; 269 handler_stack.ss_flags = SS_DISABLE; 270 internal_sigaltstack(&handler_stack, NULL); 271 return exit_code; 272 } 273 274 class ScopedStackSpaceWithGuard { 275 public: 276 explicit ScopedStackSpaceWithGuard(uptr stack_size) { 277 stack_size_ = stack_size; 278 guard_size_ = GetPageSizeCached(); 279 // FIXME: Omitting MAP_STACK here works in current kernels but might break 280 // in the future. 281 guard_start_ = (uptr)MmapOrDie(stack_size_ + guard_size_, 282 "ScopedStackWithGuard"); 283 CHECK_EQ(guard_start_, (uptr)Mprotect((uptr)guard_start_, guard_size_)); 284 } 285 ~ScopedStackSpaceWithGuard() { 286 UnmapOrDie((void *)guard_start_, stack_size_ + guard_size_); 287 } 288 void *Bottom() const { 289 return (void *)(guard_start_ + stack_size_ + guard_size_); 290 } 291 292 private: 293 uptr stack_size_; 294 uptr guard_size_; 295 uptr guard_start_; 296 }; 297 298 // We have a limitation on the stack frame size, so some stuff had to be moved 299 // into globals. 300 static __sanitizer_sigset_t blocked_sigset; 301 static __sanitizer_sigset_t old_sigset; 302 static __sanitizer_sigaction old_sigactions 303 [ARRAY_SIZE(kUnblockedSignals)]; 304 305 class StopTheWorldScope { 306 public: 307 StopTheWorldScope() { 308 // Block all signals that can be blocked safely, and install 309 // default handlers for the remaining signals. 310 // We cannot allow user-defined handlers to run while the ThreadSuspender 311 // thread is active, because they could conceivably call some libc functions 312 // which modify errno (which is shared between the two threads). 313 internal_sigfillset(&blocked_sigset); 314 for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); 315 signal_index++) { 316 // Remove the signal from the set of blocked signals. 317 internal_sigdelset(&blocked_sigset, kUnblockedSignals[signal_index]); 318 // Install the default handler. 319 __sanitizer_sigaction new_sigaction; 320 internal_memset(&new_sigaction, 0, sizeof(new_sigaction)); 321 new_sigaction.handler = SIG_DFL; 322 internal_sigfillset(&new_sigaction.sa_mask); 323 internal_sigaction_norestorer(kUnblockedSignals[signal_index], 324 &new_sigaction, &old_sigactions[signal_index]); 325 } 326 int sigprocmask_status = 327 internal_sigprocmask(SIG_BLOCK, &blocked_sigset, &old_sigset); 328 CHECK_EQ(sigprocmask_status, 0); // sigprocmask should never fail 329 // Make this process dumpable. Processes that are not dumpable cannot be 330 // attached to. 331 process_was_dumpable_ = internal_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); 332 if (!process_was_dumpable_) 333 internal_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); 334 old_die_callback = GetDieCallback(); 335 } 336 337 ~StopTheWorldScope() { 338 SetDieCallback(old_die_callback); 339 // Restore the dumpable flag. 340 if (!process_was_dumpable_) 341 internal_prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); 342 // Restore the signal handlers. 343 for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); 344 signal_index++) { 345 internal_sigaction_norestorer(kUnblockedSignals[signal_index], 346 &old_sigactions[signal_index], NULL); 347 } 348 internal_sigprocmask(SIG_SETMASK, &old_sigset, &old_sigset); 349 } 350 351 private: 352 int process_was_dumpable_; 353 }; 354 355 // When sanitizer output is being redirected to file (i.e. by using log_path), 356 // the tracer should write to the parent's log instead of trying to open a new 357 // file. Alert the logging code to the fact that we have a tracer. 358 struct ScopedSetTracerPID { 359 explicit ScopedSetTracerPID(uptr tracer_pid) { 360 stoptheworld_tracer_pid = tracer_pid; 361 stoptheworld_tracer_ppid = internal_getpid(); 362 } 363 ~ScopedSetTracerPID() { 364 stoptheworld_tracer_pid = 0; 365 stoptheworld_tracer_ppid = 0; 366 } 367 }; 368 369 void StopTheWorld(StopTheWorldCallback callback, void *argument) { 370 StopTheWorldScope in_stoptheworld; 371 // Prepare the arguments for TracerThread. 372 struct TracerThreadArgument tracer_thread_argument; 373 tracer_thread_argument.callback = callback; 374 tracer_thread_argument.callback_argument = argument; 375 tracer_thread_argument.parent_pid = internal_getpid(); 376 const uptr kTracerStackSize = 2 * 1024 * 1024; 377 ScopedStackSpaceWithGuard tracer_stack(kTracerStackSize); 378 // Block the execution of TracerThread until after we have set ptrace 379 // permissions. 380 tracer_thread_argument.mutex.Lock(); 381 uptr tracer_pid = internal_clone( 382 TracerThread, tracer_stack.Bottom(), 383 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED, 384 &tracer_thread_argument, 0 /* parent_tidptr */, 0 /* newtls */, 0 385 /* child_tidptr */); 386 int local_errno = 0; 387 if (internal_iserror(tracer_pid, &local_errno)) { 388 VReport(1, "Failed spawning a tracer thread (errno %d).\n", local_errno); 389 tracer_thread_argument.mutex.Unlock(); 390 } else { 391 ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid); 392 // On some systems we have to explicitly declare that we want to be traced 393 // by the tracer thread. 394 #ifdef PR_SET_PTRACER 395 internal_prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0); 396 #endif 397 // Allow the tracer thread to start. 398 tracer_thread_argument.mutex.Unlock(); 399 // Since errno is shared between this thread and the tracer thread, we 400 // must avoid using errno while the tracer thread is running. 401 // At this point, any signal will either be blocked or kill us, so waitpid 402 // should never return (and set errno) while the tracer thread is alive. 403 uptr waitpid_status = internal_waitpid(tracer_pid, NULL, __WALL); 404 if (internal_iserror(waitpid_status, &local_errno)) 405 VReport(1, "Waiting on the tracer thread failed (errno %d).\n", 406 local_errno); 407 } 408 } 409 410 // Platform-specific methods from SuspendedThreadsList. 411 #if SANITIZER_ANDROID && defined(__arm__) 412 typedef pt_regs regs_struct; 413 #define REG_SP ARM_sp 414 415 #elif SANITIZER_LINUX && defined(__arm__) 416 typedef user_regs regs_struct; 417 #define REG_SP uregs[13] 418 419 #elif defined(__i386__) || defined(__x86_64__) 420 typedef user_regs_struct regs_struct; 421 #if defined(__i386__) 422 #define REG_SP esp 423 #else 424 #define REG_SP rsp 425 #endif 426 427 #elif defined(__powerpc__) || defined(__powerpc64__) 428 typedef pt_regs regs_struct; 429 #define REG_SP gpr[PT_R1] 430 431 #elif defined(__mips__) 432 typedef struct user regs_struct; 433 #define REG_SP regs[EF_REG29] 434 435 #else 436 #error "Unsupported architecture" 437 #endif // SANITIZER_ANDROID && defined(__arm__) 438 439 int SuspendedThreadsList::GetRegistersAndSP(uptr index, 440 uptr *buffer, 441 uptr *sp) const { 442 pid_t tid = GetThreadID(index); 443 regs_struct regs; 444 int pterrno; 445 if (internal_iserror(internal_ptrace(PTRACE_GETREGS, tid, NULL, ®s), 446 &pterrno)) { 447 VReport(1, "Could not get registers from thread %d (errno %d).\n", tid, 448 pterrno); 449 return -1; 450 } 451 452 *sp = regs.REG_SP; 453 internal_memcpy(buffer, ®s, sizeof(regs)); 454 return 0; 455 } 456 457 uptr SuspendedThreadsList::RegisterCount() { 458 return sizeof(regs_struct) / sizeof(uptr); 459 } 460 } // namespace __sanitizer 461 462 #endif // SANITIZER_LINUX && defined(__x86_64__) 463