Bump date stamp to 20140815
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_posix_libcdep.cc
blob8e3a96f01e4d8d1c9c67e59ecd5ed976e17ded9b
1 //===-- sanitizer_posix_libcdep.cc ----------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries and implements libc-dependent POSIX-specific functions
10 // from sanitizer_libc.h.
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_platform.h"
15 #if SANITIZER_POSIX
16 #include "sanitizer_common.h"
17 #include "sanitizer_flags.h"
18 #include "sanitizer_platform_limits_posix.h"
19 #include "sanitizer_stacktrace.h"
21 #include <errno.h>
22 #include <pthread.h>
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <sys/mman.h>
26 #include <sys/resource.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <unistd.h>
31 namespace __sanitizer {
33 u32 GetUid() {
34 return getuid();
37 uptr GetThreadSelf() {
38 return (uptr)pthread_self();
41 void FlushUnneededShadowMemory(uptr addr, uptr size) {
42 madvise((void*)addr, size, MADV_DONTNEED);
45 void DisableCoreDumper() {
46 struct rlimit nocore;
47 nocore.rlim_cur = 0;
48 nocore.rlim_max = 0;
49 setrlimit(RLIMIT_CORE, &nocore);
52 bool StackSizeIsUnlimited() {
53 struct rlimit rlim;
54 CHECK_EQ(0, getrlimit(RLIMIT_STACK, &rlim));
55 return ((uptr)rlim.rlim_cur == (uptr)-1);
58 void SetStackSizeLimitInBytes(uptr limit) {
59 struct rlimit rlim;
60 rlim.rlim_cur = limit;
61 rlim.rlim_max = limit;
62 if (setrlimit(RLIMIT_STACK, &rlim)) {
63 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno);
64 Die();
66 CHECK(!StackSizeIsUnlimited());
69 void SleepForSeconds(int seconds) {
70 sleep(seconds);
73 void SleepForMillis(int millis) {
74 usleep(millis * 1000);
77 void Abort() {
78 abort();
81 int Atexit(void (*function)(void)) {
82 #ifndef SANITIZER_GO
83 return atexit(function);
84 #else
85 return 0;
86 #endif
89 int internal_isatty(fd_t fd) {
90 return isatty(fd);
93 #ifndef SANITIZER_GO
94 // TODO(glider): different tools may require different altstack size.
95 static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough.
97 void SetAlternateSignalStack() {
98 stack_t altstack, oldstack;
99 CHECK_EQ(0, sigaltstack(0, &oldstack));
100 // If the alternate stack is already in place, do nothing.
101 // Android always sets an alternate stack, but it's too small for us.
102 if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return;
103 // TODO(glider): the mapped stack should have the MAP_STACK flag in the
104 // future. It is not required by man 2 sigaltstack now (they're using
105 // malloc()).
106 void* base = MmapOrDie(kAltStackSize, __func__);
107 altstack.ss_sp = (char*) base;
108 altstack.ss_flags = 0;
109 altstack.ss_size = kAltStackSize;
110 CHECK_EQ(0, sigaltstack(&altstack, 0));
113 void UnsetAlternateSignalStack() {
114 stack_t altstack, oldstack;
115 altstack.ss_sp = 0;
116 altstack.ss_flags = SS_DISABLE;
117 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin.
118 CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
119 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
122 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
123 static void MaybeInstallSigaction(int signum,
124 SignalHandlerType handler) {
125 if (!IsDeadlySignal(signum))
126 return;
127 struct sigaction sigact;
128 internal_memset(&sigact, 0, sizeof(sigact));
129 sigact.sa_sigaction = (sa_sigaction_t)handler;
130 sigact.sa_flags = SA_SIGINFO;
131 if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
132 CHECK_EQ(0, internal_sigaction(signum, &sigact, 0));
133 VReport(1, "Installed the sigaction for signal %d\n", signum);
136 void InstallDeadlySignalHandlers(SignalHandlerType handler) {
137 // Set the alternate signal stack for the main thread.
138 // This will cause SetAlternateSignalStack to be called twice, but the stack
139 // will be actually set only once.
140 if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
141 MaybeInstallSigaction(SIGSEGV, handler);
142 MaybeInstallSigaction(SIGBUS, handler);
144 #endif // SANITIZER_GO
146 } // namespace __sanitizer
148 #endif // SANITIZER_POSIX