sanitizer_stoptheworld_linux_libcdep.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
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
70COMPILER_CHECK(sizeof(SuspendedThreadID) == sizeof(pid_t));
71
72namespace __sanitizer {
73// This class handles thread suspending/unsuspending in the tracer thread.
74class 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
92bool 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
126void 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
142void 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
148bool 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.
171static 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).
175static const int kUnblockedSignals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV,
176                                         SIGBUS, SIGXCPU, SIGXFSZ };
177
178// Structure for passing arguments into the tracer thread.
179struct 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
188static DieCallbackType old_die_callback;
189
190// Signal handler to wake up suspended threads when the tracer thread dies.
191void 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
201static 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.
215static const int kHandlerStackSize = 4096;
216
217// This function will be run as a cloned task.
218static 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
274class 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.
300static __sanitizer_sigset_t blocked_sigset;
301static __sanitizer_sigset_t old_sigset;
302static __sanitizer_sigaction old_sigactions
303    [ARRAY_SIZE(kUnblockedSignals)];
304
305class 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.
358struct 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
369void 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__)
412typedef pt_regs regs_struct;
413#define REG_SP ARM_sp
414
415#elif SANITIZER_LINUX && defined(__arm__)
416typedef user_regs regs_struct;
417#define REG_SP uregs[13]
418
419#elif defined(__i386__) || defined(__x86_64__)
420typedef 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__)
428typedef pt_regs regs_struct;
429#define REG_SP gpr[PT_R1]
430
431#elif defined(__mips__)
432typedef 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
439int 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, &regs),
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, &regs, sizeof(regs));
454  return 0;
455}
456
457uptr SuspendedThreadsList::RegisterCount() {
458  return sizeof(regs_struct) / sizeof(uptr);
459}
460}  // namespace __sanitizer
461
462#endif  // SANITIZER_LINUX && defined(__x86_64__)
463