1 //===-- sanitizer_posix_libcdep.cc ----------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between AddressSanitizer and ThreadSanitizer
11 // run-time libraries and implements libc-dependent POSIX-specific functions
12 // from sanitizer_libc.h.
13 //===----------------------------------------------------------------------===//
15 #include "sanitizer_platform.h"
18 #include "sanitizer_common.h"
19 #include "sanitizer_flags.h"
20 #include "sanitizer_platform_limits_posix.h"
21 #include "sanitizer_stacktrace.h"
28 #include <sys/resource.h>
30 #include <sys/types.h>
33 namespace __sanitizer {
39 uptr GetThreadSelf() {
40 return (uptr)pthread_self();
43 void FlushUnneededShadowMemory(uptr addr, uptr size) {
44 madvise((void*)addr, size, MADV_DONTNEED);
47 void NoHugePagesInRegion(uptr addr, uptr size) {
48 #ifdef MADV_NOHUGEPAGE // May not be defined on old systems.
49 madvise((void *)addr, size, MADV_NOHUGEPAGE);
50 #endif // MADV_NOHUGEPAGE
53 void DontDumpShadowMemory(uptr addr, uptr length) {
55 madvise((void *)addr, length, MADV_DONTDUMP);
59 static rlim_t getlim(int res) {
61 CHECK_EQ(0, getrlimit(res, &rlim));
65 static void setlim(int res, rlim_t lim) {
66 // The following magic is to prevent clang from replacing it with memset.
67 volatile struct rlimit rlim;
70 if (setrlimit(res, const_cast<struct rlimit *>(&rlim))) {
71 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno);
76 void DisableCoreDumperIfNecessary() {
77 if (common_flags()->disable_coredump) {
78 setlim(RLIMIT_CORE, 0);
82 bool StackSizeIsUnlimited() {
83 rlim_t stack_size = getlim(RLIMIT_STACK);
84 return (stack_size == RLIM_INFINITY);
87 void SetStackSizeLimitInBytes(uptr limit) {
88 setlim(RLIMIT_STACK, (rlim_t)limit);
89 CHECK(!StackSizeIsUnlimited());
92 bool AddressSpaceIsUnlimited() {
93 rlim_t as_size = getlim(RLIMIT_AS);
94 return (as_size == RLIM_INFINITY);
97 void SetAddressSpaceUnlimited() {
98 setlim(RLIMIT_AS, RLIM_INFINITY);
99 CHECK(AddressSpaceIsUnlimited());
102 void SleepForSeconds(int seconds) {
106 void SleepForMillis(int millis) {
107 usleep(millis * 1000);
114 int Atexit(void (*function)(void)) {
116 return atexit(function);
122 int internal_isatty(fd_t fd) {
127 // TODO(glider): different tools may require different altstack size.
128 static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough.
130 void SetAlternateSignalStack() {
131 stack_t altstack, oldstack;
132 CHECK_EQ(0, sigaltstack(0, &oldstack));
133 // If the alternate stack is already in place, do nothing.
134 // Android always sets an alternate stack, but it's too small for us.
135 if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return;
136 // TODO(glider): the mapped stack should have the MAP_STACK flag in the
137 // future. It is not required by man 2 sigaltstack now (they're using
139 void* base = MmapOrDie(kAltStackSize, __func__);
140 altstack.ss_sp = (char*) base;
141 altstack.ss_flags = 0;
142 altstack.ss_size = kAltStackSize;
143 CHECK_EQ(0, sigaltstack(&altstack, 0));
146 void UnsetAlternateSignalStack() {
147 stack_t altstack, oldstack;
149 altstack.ss_flags = SS_DISABLE;
150 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin.
151 CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
152 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
155 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
156 static void MaybeInstallSigaction(int signum,
157 SignalHandlerType handler) {
158 if (!IsDeadlySignal(signum))
160 struct sigaction sigact;
161 internal_memset(&sigact, 0, sizeof(sigact));
162 sigact.sa_sigaction = (sa_sigaction_t)handler;
163 // Do not block the signal from being received in that signal's handler.
164 // Clients are responsible for handling this correctly.
165 sigact.sa_flags = SA_SIGINFO | SA_NODEFER;
166 if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
167 CHECK_EQ(0, internal_sigaction(signum, &sigact, 0));
168 VReport(1, "Installed the sigaction for signal %d\n", signum);
171 void InstallDeadlySignalHandlers(SignalHandlerType handler) {
172 // Set the alternate signal stack for the main thread.
173 // This will cause SetAlternateSignalStack to be called twice, but the stack
174 // will be actually set only once.
175 if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
176 MaybeInstallSigaction(SIGSEGV, handler);
177 MaybeInstallSigaction(SIGBUS, handler);
179 #endif // SANITIZER_GO
181 bool IsAccessibleMemoryRange(uptr beg, uptr size) {
182 uptr page_size = GetPageSizeCached();
183 // Checking too large memory ranges is slow.
184 CHECK_LT(size, page_size * 10);
189 internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size);
192 if (internal_iserror(bytes_written, &write_errno)) {
193 CHECK_EQ(EFAULT, write_errno);
196 result = (bytes_written == size);
198 internal_close(sock_pair[0]);
199 internal_close(sock_pair[1]);
203 } // namespace __sanitizer
205 #endif // SANITIZER_POSIX