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:
ThreadSuspender(pid_t pid)75 explicit ThreadSuspender(pid_t pid)
76 : pid_(pid) {
77 CHECK_GE(pid, 0);
78 }
79 bool SuspendAllThreads();
80 void ResumeAllThreads();
81 void KillAllThreads();
suspended_threads_list()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
SuspendThread(SuspendedThreadID thread_id)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
ResumeAllThreads()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
KillAllThreads()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
SuspendAllThreads()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.
TracerThreadSignalHandler(int signum,siginfo_t * siginfo,void *)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.
TracerThread(void * argument)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
StopTheWorld(StopTheWorldCallback callback,void * argument)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