1705e310b98e85f893a69bccad1a9c066e2f4c277Peter Collingbourne//===-- sanitizer_stoptheworld_linux_libcdep.cc ---------------------------===// 23614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 33614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// The LLVM Compiler Infrastructure 43614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 53614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This file is distributed under the University of Illinois Open Source 63614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// License. See LICENSE.TXT for details. 73614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 83614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===----------------------------------------------------------------------===// 93614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 103614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// See sanitizer_stoptheworld.h for details. 113614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This implementation was inspired by Markus Gutschke's linuxthreads.cc. 123614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 133614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===----------------------------------------------------------------------===// 143614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov 1624e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_platform.h" 17cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev#if SANITIZER_LINUX && defined(__x86_64__) 183614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 193614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_stoptheworld.h" 203614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 215f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov#include "sanitizer_platform_limits_posix.h" 225f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov 233614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include <errno.h> 24cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev#include <sched.h> // for CLONE_* definitions 253614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include <stddef.h> 263614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include <sys/prctl.h> // for PR_* definitions 273614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include <sys/ptrace.h> // for PTRACE_* definitions 283614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include <sys/types.h> // for pid_t 29115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#if SANITIZER_ANDROID && defined(__arm__) 30bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov# include <linux/user.h> // for pt_regs 31bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov#else 32bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov# include <sys/user.h> // for user_regs_struct 33bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov#endif 343614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include <sys/wait.h> // for signal-related stuff 353614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 365f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov#ifdef sa_handler 375f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov# undef sa_handler 385f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov#endif 395f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov 405f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov#ifdef sa_sigaction 415f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov# undef sa_sigaction 425f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov#endif 435f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov 443614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_common.h" 458f4cece84c528071202daae54593981e7677dcf9Dmitry Vyukov#include "sanitizer_flags.h" 463614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_libc.h" 473614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_linux.h" 483614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_mutex.h" 4949960be4dd7c038b26784cee046cc6637e32dc57Dmitry Vyukov#include "sanitizer_placement_new.h" 503614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 513614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This module works by spawning a Linux task which then attaches to every 523614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// thread in the caller process with ptrace. This suspends the threads, and 533614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// PTRACE_GETREGS can then be used to obtain their register state. The callback 543614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// supplied to StopTheWorld() is run in the tracer task while the threads are 553614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// suspended. 563614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// The tracer task must be placed in a different thread group for ptrace to 573614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// work, so it cannot be spawned as a pthread. Instead, we use the low-level 583614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// clone() interface (we want to share the address space with the caller 593614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// process, so we prefer clone() over fork()). 603614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 612191fcaa9658166c0c6e9c91013fefc015741395Sergey Matveev// We don't use any libc functions, relying instead on direct syscalls. There 622191fcaa9658166c0c6e9c91013fefc015741395Sergey Matveev// are two reasons for this: 633614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 1. calling a library function while threads are suspended could cause a 643614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// deadlock, if one of the treads happens to be holding a libc lock; 653614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 2. it's generally not safe to call libc functions from the tracer task, 663614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// because clone() does not set up a thread-local storage for it. Any 673614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// thread-local variables used by libc will be shared between the tracer task 683614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// and the thread which spawned it. 693614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 703614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander PotapenkoCOMPILER_CHECK(sizeof(SuspendedThreadID) == sizeof(pid_t)); 713614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 723614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkonamespace __sanitizer { 733614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This class handles thread suspending/unsuspending in the tracer thread. 743614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkoclass ThreadSuspender { 753614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko public: 763614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko explicit ThreadSuspender(pid_t pid) 773614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko : pid_(pid) { 783614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko CHECK_GE(pid, 0); 793614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 803614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko bool SuspendAllThreads(); 813614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko void ResumeAllThreads(); 823614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko void KillAllThreads(); 833614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko SuspendedThreadsList &suspended_threads_list() { 843614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return suspended_threads_list_; 853614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 863614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko private: 873614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko SuspendedThreadsList suspended_threads_list_; 883614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko pid_t pid_; 893614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko bool SuspendThread(SuspendedThreadID thread_id); 903614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko}; 913614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 923614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkobool ThreadSuspender::SuspendThread(SuspendedThreadID thread_id) { 933614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Are we already attached to this thread? 943614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Currently this check takes linear time, however the number of threads is 953614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // usually small. 963614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko if (suspended_threads_list_.Contains(thread_id)) 973614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return false; 989578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne int pterrno; 999578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne if (internal_iserror(internal_ptrace(PTRACE_ATTACH, thread_id, NULL, NULL), 1009578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne &pterrno)) { 1013614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Either the thread is dead, or something prevented us from attaching. 1023614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Log this event and move on. 1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Could not attach to thread %d (errno %d).\n", thread_id, 1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pterrno); 1053614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return false; 1063614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } else { 1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Attached to thread %d.\n", thread_id); 1083614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // The thread is not guaranteed to stop before ptrace returns, so we must 1093614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // wait on it. 1109578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne uptr waitpid_status; 1113614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko HANDLE_EINTR(waitpid_status, internal_waitpid(thread_id, NULL, __WALL)); 1129578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne int wperrno; 1139578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne if (internal_iserror(waitpid_status, &wperrno)) { 1143614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Got a ECHILD error. I don't think this situation is possible, but it 1153614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // doesn't hurt to report it. 1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Waiting on thread %d failed, detaching (errno %d).\n", 1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines thread_id, wperrno); 1183614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_ptrace(PTRACE_DETACH, thread_id, NULL, NULL); 1193614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return false; 1203614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 1213614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko suspended_threads_list_.Append(thread_id); 1223614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return true; 1233614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 1243614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 1253614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1263614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkovoid ThreadSuspender::ResumeAllThreads() { 1273614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++) { 1283614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko pid_t tid = suspended_threads_list_.GetThreadID(i); 1299578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne int pterrno; 1309578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne if (!internal_iserror(internal_ptrace(PTRACE_DETACH, tid, NULL, NULL), 1319578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne &pterrno)) { 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Detached from thread %d.\n", tid); 1333614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } else { 1343614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Either the thread is dead, or we are already detached. 1353614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // The latter case is possible, for instance, if this function was called 1363614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // from a signal handler. 1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Could not detach from thread %d (errno %d).\n", tid, pterrno); 1383614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 1393614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 1403614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 1413614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1423614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkovoid ThreadSuspender::KillAllThreads() { 1433614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++) 1443614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_ptrace(PTRACE_KILL, suspended_threads_list_.GetThreadID(i), 1453614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko NULL, NULL); 1463614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 1473614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1483614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkobool ThreadSuspender::SuspendAllThreads() { 14910f3ab775088bec69dd9e7b611f9b4e152f629bcAlexey Samsonov ThreadLister thread_lister(pid_); 1503614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko bool added_threads; 1513614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko do { 1523614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Run through the directory entries once. 1533614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko added_threads = false; 15410f3ab775088bec69dd9e7b611f9b4e152f629bcAlexey Samsonov pid_t tid = thread_lister.GetNextTID(); 1553614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko while (tid >= 0) { 1563614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko if (SuspendThread(tid)) 1573614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko added_threads = true; 15810f3ab775088bec69dd9e7b611f9b4e152f629bcAlexey Samsonov tid = thread_lister.GetNextTID(); 1593614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 16010f3ab775088bec69dd9e7b611f9b4e152f629bcAlexey Samsonov if (thread_lister.error()) { 1613614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Detach threads and fail. 1623614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko ResumeAllThreads(); 1633614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return false; 1643614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 16510f3ab775088bec69dd9e7b611f9b4e152f629bcAlexey Samsonov thread_lister.Reset(); 1663614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } while (added_threads); 1673614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return true; 1683614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 1693614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1703614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Pointer to the ThreadSuspender instance for use in signal handler. 1713614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkostatic ThreadSuspender *thread_suspender_instance = NULL; 1723614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1733614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Signals that should not be blocked (this is used in the parent thread as well 1743614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// as the tracer thread). 1753614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkostatic const int kUnblockedSignals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, 1763614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko SIGBUS, SIGXCPU, SIGXFSZ }; 1773614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 1783614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Structure for passing arguments into the tracer thread. 1793614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkostruct TracerThreadArgument { 1803614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko StopTheWorldCallback callback; 1813614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko void *callback_argument; 182d41fa1b7f2afe5dd78cd4e635e16fd5f079b0318Sergey Matveev // The tracer thread waits on this mutex while the parent finishes its 1836d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov // preparations. 1846d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov BlockingMutex mutex; 185d41fa1b7f2afe5dd78cd4e635e16fd5f079b0318Sergey Matveev uptr parent_pid; 1863614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko}; 1873614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 18890629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveevstatic DieCallbackType old_die_callback; 18990629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev 1903614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Signal handler to wake up suspended threads when the tracer thread dies. 1915f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukovvoid TracerThreadSignalHandler(int signum, void *siginfo, void *) { 1923614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko if (thread_suspender_instance != NULL) { 1933614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko if (signum == SIGABRT) 1943614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko thread_suspender_instance->KillAllThreads(); 1953614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko else 1963614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko thread_suspender_instance->ResumeAllThreads(); 1973614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 1983614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal__exit((signum == SIGABRT) ? 1 : 2); 1993614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 2003614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 20190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveevstatic void TracerThreadDieCallback() { 20290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // Generally a call to Die() in the tracer thread should be fatal to the 20390629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // parent process as well, because they share the address space. 20490629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // This really only works correctly if all the threads are suspended at this 20590629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // point. So we correctly handle calls to Die() from within the callback, but 20690629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // not those that happen before or after the callback. Hopefully there aren't 20790629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // a lot of opportunities for that to happen... 20890629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev if (thread_suspender_instance) 20990629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev thread_suspender_instance->KillAllThreads(); 21090629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev if (old_die_callback) 21190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev old_die_callback(); 21290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev} 21390629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev 2143614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Size of alternative stack for signal handlers in the tracer thread. 2153614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkostatic const int kHandlerStackSize = 4096; 2163614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 2173614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This function will be run as a cloned task. 2186d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonovstatic int TracerThread(void* argument) { 2193614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko TracerThreadArgument *tracer_thread_argument = 2203614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko (TracerThreadArgument *)argument; 2213614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 22223a7a43da615bceedefe42b8398b82939e6eeb2dSergey Matveev internal_prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 22323a7a43da615bceedefe42b8398b82939e6eeb2dSergey Matveev // Check if parent is already dead. 224d41fa1b7f2afe5dd78cd4e635e16fd5f079b0318Sergey Matveev if (internal_getppid() != tracer_thread_argument->parent_pid) 22523a7a43da615bceedefe42b8398b82939e6eeb2dSergey Matveev internal__exit(4); 22623a7a43da615bceedefe42b8398b82939e6eeb2dSergey Matveev 2273614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Wait for the parent thread to finish preparations. 2286d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov tracer_thread_argument->mutex.Lock(); 2296d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov tracer_thread_argument->mutex.Unlock(); 2303614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 23190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev SetDieCallback(TracerThreadDieCallback); 23290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev 2333614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko ThreadSuspender thread_suspender(internal_getppid()); 2343614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Global pointer for the signal handler. 2353614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko thread_suspender_instance = &thread_suspender; 2363614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 2373614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Alternate stack for signal handling. 2383614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize); 2393614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko struct sigaltstack handler_stack; 2403614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_memset(&handler_stack, 0, sizeof(handler_stack)); 2413614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko handler_stack.ss_sp = handler_stack_memory.data(); 2423614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko handler_stack.ss_size = kHandlerStackSize; 2433614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_sigaltstack(&handler_stack, NULL); 2443614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 2453614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Install our handler for fatal signals. Other signals should be blocked by 2463614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // the mask we inherited from the caller thread. 2473614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); 2483614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko signal_index++) { 2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __sanitizer_sigaction new_sigaction; 2503614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_memset(&new_sigaction, 0, sizeof(new_sigaction)); 2510f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov new_sigaction.sigaction = TracerThreadSignalHandler; 2523614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko new_sigaction.sa_flags = SA_ONSTACK | SA_SIGINFO; 2530f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov internal_sigfillset(&new_sigaction.sa_mask); 2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines internal_sigaction_norestorer(kUnblockedSignals[signal_index], 2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &new_sigaction, NULL); 2563614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 2573614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 2583614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko int exit_code = 0; 2593614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko if (!thread_suspender.SuspendAllThreads()) { 2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Failed suspending threads.\n"); 2613614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko exit_code = 3; 2623614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } else { 2633614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko tracer_thread_argument->callback(thread_suspender.suspended_threads_list(), 2643614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko tracer_thread_argument->callback_argument); 2653614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko thread_suspender.ResumeAllThreads(); 2663614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko exit_code = 0; 2673614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 2683614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko thread_suspender_instance = NULL; 2693614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko handler_stack.ss_flags = SS_DISABLE; 2703614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_sigaltstack(&handler_stack, NULL); 2713614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return exit_code; 2723614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 2733614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 274fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenkoclass ScopedStackSpaceWithGuard { 275fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko public: 276fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko explicit ScopedStackSpaceWithGuard(uptr stack_size) { 277fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko stack_size_ = stack_size; 278fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko guard_size_ = GetPageSizeCached(); 279fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko // FIXME: Omitting MAP_STACK here works in current kernels but might break 280fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko // in the future. 281fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko guard_start_ = (uptr)MmapOrDie(stack_size_ + guard_size_, 282fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko "ScopedStackWithGuard"); 283fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko CHECK_EQ(guard_start_, (uptr)Mprotect((uptr)guard_start_, guard_size_)); 284fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko } 285fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko ~ScopedStackSpaceWithGuard() { 286fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko UnmapOrDie((void *)guard_start_, stack_size_ + guard_size_); 287fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko } 288fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko void *Bottom() const { 289fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko return (void *)(guard_start_ + stack_size_ + guard_size_); 290fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko } 291fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko 292fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko private: 293fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko uptr stack_size_; 294fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko uptr guard_size_; 295fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko uptr guard_start_; 296fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko}; 297fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko 29890629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev// We have a limitation on the stack frame size, so some stuff had to be moved 29990629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev// into globals. 3002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic __sanitizer_sigset_t blocked_sigset; 3012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic __sanitizer_sigset_t old_sigset; 3022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic __sanitizer_sigaction old_sigactions 3035f4984db88b7b67539f62d7653b928aeadf91b16Dmitry Vyukov [ARRAY_SIZE(kUnblockedSignals)]; 30449960be4dd7c038b26784cee046cc6637e32dc57Dmitry Vyukov 30590629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveevclass StopTheWorldScope { 30690629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev public: 30790629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev StopTheWorldScope() { 308c154820b43052cfc54ee20752a3232aa8e6c7843Alexey Samsonov // Block all signals that can be blocked safely, and install 309c154820b43052cfc54ee20752a3232aa8e6c7843Alexey Samsonov // default handlers for the remaining signals. 31090629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // We cannot allow user-defined handlers to run while the ThreadSuspender 31190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // thread is active, because they could conceivably call some libc functions 31290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // which modify errno (which is shared between the two threads). 3130f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov internal_sigfillset(&blocked_sigset); 31490629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); 31590629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev signal_index++) { 31690629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // Remove the signal from the set of blocked signals. 3170f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov internal_sigdelset(&blocked_sigset, kUnblockedSignals[signal_index]); 31890629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // Install the default handler. 3192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __sanitizer_sigaction new_sigaction; 32090629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev internal_memset(&new_sigaction, 0, sizeof(new_sigaction)); 3210f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov new_sigaction.handler = SIG_DFL; 3220f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov internal_sigfillset(&new_sigaction.sa_mask); 3232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines internal_sigaction_norestorer(kUnblockedSignals[signal_index], 3242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &new_sigaction, &old_sigactions[signal_index]); 32590629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev } 32690629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev int sigprocmask_status = 3270f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov internal_sigprocmask(SIG_BLOCK, &blocked_sigset, &old_sigset); 32890629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev CHECK_EQ(sigprocmask_status, 0); // sigprocmask should never fail 32990629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // Make this process dumpable. Processes that are not dumpable cannot be 33090629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // attached to. 33190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev process_was_dumpable_ = internal_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); 33290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev if (!process_was_dumpable_) 33390629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev internal_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); 33490629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev old_die_callback = GetDieCallback(); 33590629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev } 33690629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev 33790629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev ~StopTheWorldScope() { 33890629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev SetDieCallback(old_die_callback); 33990629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // Restore the dumpable flag. 34090629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev if (!process_was_dumpable_) 34190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev internal_prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); 34290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev // Restore the signal handlers. 34390629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); 34490629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev signal_index++) { 3452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines internal_sigaction_norestorer(kUnblockedSignals[signal_index], 3462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &old_sigactions[signal_index], NULL); 34790629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev } 3480f7a2acb3326a5900d1a1339ebf959b14b372e0dDmitry Vyukov internal_sigprocmask(SIG_SETMASK, &old_sigset, &old_sigset); 3493614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 350c154820b43052cfc54ee20752a3232aa8e6c7843Alexey Samsonov 35190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev private: 35290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev int process_was_dumpable_; 35390629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev}; 35490629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev 3552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// When sanitizer output is being redirected to file (i.e. by using log_path), 3562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// the tracer should write to the parent's log instead of trying to open a new 3572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// file. Alert the logging code to the fact that we have a tracer. 3582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct ScopedSetTracerPID { 3592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines explicit ScopedSetTracerPID(uptr tracer_pid) { 3602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stoptheworld_tracer_pid = tracer_pid; 3612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stoptheworld_tracer_ppid = internal_getpid(); 3622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 3632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ~ScopedSetTracerPID() { 3642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stoptheworld_tracer_pid = 0; 3652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stoptheworld_tracer_ppid = 0; 3662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 3672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}; 3682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 36990629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveevvoid StopTheWorld(StopTheWorldCallback callback, void *argument) { 37090629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev StopTheWorldScope in_stoptheworld; 3713614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Prepare the arguments for TracerThread. 3723614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko struct TracerThreadArgument tracer_thread_argument; 3733614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko tracer_thread_argument.callback = callback; 3743614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko tracer_thread_argument.callback_argument = argument; 375d41fa1b7f2afe5dd78cd4e635e16fd5f079b0318Sergey Matveev tracer_thread_argument.parent_pid = internal_getpid(); 376fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko const uptr kTracerStackSize = 2 * 1024 * 1024; 377fd8726cae237495a8f63d12e6e026290fd5f4787Alexander Potapenko ScopedStackSpaceWithGuard tracer_stack(kTracerStackSize); 3786d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov // Block the execution of TracerThread until after we have set ptrace 3796d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov // permissions. 3806d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov tracer_thread_argument.mutex.Lock(); 381cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev uptr tracer_pid = internal_clone( 382cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev TracerThread, tracer_stack.Bottom(), 383cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED, 384cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev &tracer_thread_argument, 0 /* parent_tidptr */, 0 /* newtls */, 0 385cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev /* child_tidptr */); 386cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev int local_errno = 0; 387cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev if (internal_iserror(tracer_pid, &local_errno)) { 3882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Failed spawning a tracer thread (errno %d).\n", local_errno); 3896d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov tracer_thread_argument.mutex.Unlock(); 3903614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } else { 3912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid); 3923614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // On some systems we have to explicitly declare that we want to be traced 3933614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // by the tracer thread. 3943614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#ifdef PR_SET_PTRACER 3953614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko internal_prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0); 3963614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#endif 3973614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Allow the tracer thread to start. 3986d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov tracer_thread_argument.mutex.Unlock(); 3993614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Since errno is shared between this thread and the tracer thread, we 4003614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // must avoid using errno while the tracer thread is running. 4013614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // At this point, any signal will either be blocked or kill us, so waitpid 4023614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // should never return (and set errno) while the tracer thread is alive. 4039578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne uptr waitpid_status = internal_waitpid(tracer_pid, NULL, __WALL); 4042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (internal_iserror(waitpid_status, &local_errno)) 4052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Waiting on the tracer thread failed (errno %d).\n", 4062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines local_errno); 4073614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 4083614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} 4093614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 41053c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko// Platform-specific methods from SuspendedThreadsList. 411115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#if SANITIZER_ANDROID && defined(__arm__) 412bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonovtypedef pt_regs regs_struct; 413115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#define REG_SP ARM_sp 414115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev 415115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#elif SANITIZER_LINUX && defined(__arm__) 416115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveevtypedef user_regs regs_struct; 417115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#define REG_SP uregs[13] 418115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev 419115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#elif defined(__i386__) || defined(__x86_64__) 420bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonovtypedef user_regs_struct regs_struct; 421115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#if defined(__i386__) 422115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#define REG_SP esp 423115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#else 424115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#define REG_SP rsp 425bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov#endif 426bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov 427f931da85ce8668751628ded926ecad013c5d6f1aKostya Serebryany#elif defined(__powerpc__) || defined(__powerpc64__) 428f931da85ce8668751628ded926ecad013c5d6f1aKostya Serebryanytypedef pt_regs regs_struct; 429f931da85ce8668751628ded926ecad013c5d6f1aKostya Serebryany#define REG_SP gpr[PT_R1] 430f931da85ce8668751628ded926ecad013c5d6f1aKostya Serebryany 43140527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany#elif defined(__mips__) 43240527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryanytypedef struct user regs_struct; 43340527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany#define REG_SP regs[EF_REG29] 43440527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany 435115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#else 436115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#error "Unsupported architecture" 437115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev#endif // SANITIZER_ANDROID && defined(__arm__) 438115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev 43953c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenkoint SuspendedThreadsList::GetRegistersAndSP(uptr index, 44053c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko uptr *buffer, 44153c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko uptr *sp) const { 44253c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko pid_t tid = GetThreadID(index); 443bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov regs_struct regs; 4449578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne int pterrno; 4459578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne if (internal_iserror(internal_ptrace(PTRACE_GETREGS, tid, NULL, ®s), 4469578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne &pterrno)) { 4472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Could not get registers from thread %d (errno %d).\n", tid, 4482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pterrno); 44953c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko return -1; 45053c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko } 451115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev 452115accb935dc1464d78e041d2aaf571044dfdc60Sergey Matveev *sp = regs.REG_SP; 45353c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko internal_memcpy(buffer, ®s, sizeof(regs)); 45453c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko return 0; 45553c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko} 45653c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko 45753c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenkouptr SuspendedThreadsList::RegisterCount() { 458bb090b56ca283396f17b9a3ef2e8f00544a21385Alexey Samsonov return sizeof(regs_struct) / sizeof(uptr); 45953c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko} 4603614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} // namespace __sanitizer 4613614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 462cb339108cca40fb4c1ed520656cb6cb75889a237Sergey Matveev#endif // SANITIZER_LINUX && defined(__x86_64__) 463