1 //===-- sanitizer_posix_libcdep.cc ----------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
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"
16 #include "sanitizer_common.h"
17 #include "sanitizer_flags.h"
18 #include "sanitizer_platform_limits_posix.h"
19 #include "sanitizer_stacktrace.h"
26 #include <sys/resource.h>
28 #include <sys/types.h>
31 namespace __sanitizer
{
37 uptr
GetThreadSelf() {
38 return (uptr
)pthread_self();
41 void FlushUnneededShadowMemory(uptr addr
, uptr size
) {
42 madvise((void*)addr
, size
, MADV_DONTNEED
);
45 static rlim_t
getlim(int res
) {
47 CHECK_EQ(0, getrlimit(res
, &rlim
));
51 static void setlim(int res
, rlim_t lim
) {
52 // The following magic is to prevent clang from replacing it with memset.
53 volatile struct rlimit rlim
;
56 if (setrlimit(res
, (struct rlimit
*)&rlim
)) {
57 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName
, errno
);
62 void DisableCoreDumperIfNecessary() {
63 if (common_flags()->disable_coredump
) {
64 setlim(RLIMIT_CORE
, 0);
68 bool StackSizeIsUnlimited() {
69 rlim_t stack_size
= getlim(RLIMIT_STACK
);
70 return (stack_size
== RLIM_INFINITY
);
73 void SetStackSizeLimitInBytes(uptr limit
) {
74 setlim(RLIMIT_STACK
, (rlim_t
)limit
);
75 CHECK(!StackSizeIsUnlimited());
78 bool AddressSpaceIsUnlimited() {
79 rlim_t as_size
= getlim(RLIMIT_AS
);
80 return (as_size
== RLIM_INFINITY
);
83 void SetAddressSpaceUnlimited() {
84 setlim(RLIMIT_AS
, RLIM_INFINITY
);
85 CHECK(AddressSpaceIsUnlimited());
88 void SleepForSeconds(int seconds
) {
92 void SleepForMillis(int millis
) {
93 usleep(millis
* 1000);
100 int Atexit(void (*function
)(void)) {
102 return atexit(function
);
108 int internal_isatty(fd_t fd
) {
113 // TODO(glider): different tools may require different altstack size.
114 static const uptr kAltStackSize
= SIGSTKSZ
* 4; // SIGSTKSZ is not enough.
116 void SetAlternateSignalStack() {
117 stack_t altstack
, oldstack
;
118 CHECK_EQ(0, sigaltstack(0, &oldstack
));
119 // If the alternate stack is already in place, do nothing.
120 // Android always sets an alternate stack, but it's too small for us.
121 if (!SANITIZER_ANDROID
&& !(oldstack
.ss_flags
& SS_DISABLE
)) return;
122 // TODO(glider): the mapped stack should have the MAP_STACK flag in the
123 // future. It is not required by man 2 sigaltstack now (they're using
125 void* base
= MmapOrDie(kAltStackSize
, __func__
);
126 altstack
.ss_sp
= (char*) base
;
127 altstack
.ss_flags
= 0;
128 altstack
.ss_size
= kAltStackSize
;
129 CHECK_EQ(0, sigaltstack(&altstack
, 0));
132 void UnsetAlternateSignalStack() {
133 stack_t altstack
, oldstack
;
135 altstack
.ss_flags
= SS_DISABLE
;
136 altstack
.ss_size
= kAltStackSize
; // Some sane value required on Darwin.
137 CHECK_EQ(0, sigaltstack(&altstack
, &oldstack
));
138 UnmapOrDie(oldstack
.ss_sp
, oldstack
.ss_size
);
141 typedef void (*sa_sigaction_t
)(int, siginfo_t
*, void *);
142 static void MaybeInstallSigaction(int signum
,
143 SignalHandlerType handler
) {
144 if (!IsDeadlySignal(signum
))
146 struct sigaction sigact
;
147 internal_memset(&sigact
, 0, sizeof(sigact
));
148 sigact
.sa_sigaction
= (sa_sigaction_t
)handler
;
149 // Do not block the signal from being received in that signal's handler.
150 // Clients are responsible for handling this correctly.
151 sigact
.sa_flags
= SA_SIGINFO
| SA_NODEFER
;
152 if (common_flags()->use_sigaltstack
) sigact
.sa_flags
|= SA_ONSTACK
;
153 CHECK_EQ(0, internal_sigaction(signum
, &sigact
, 0));
154 VReport(1, "Installed the sigaction for signal %d\n", signum
);
157 void InstallDeadlySignalHandlers(SignalHandlerType handler
) {
158 // Set the alternate signal stack for the main thread.
159 // This will cause SetAlternateSignalStack to be called twice, but the stack
160 // will be actually set only once.
161 if (common_flags()->use_sigaltstack
) SetAlternateSignalStack();
162 MaybeInstallSigaction(SIGSEGV
, handler
);
163 MaybeInstallSigaction(SIGBUS
, handler
);
165 #endif // SANITIZER_GO
167 bool IsAccessibleMemoryRange(uptr beg
, uptr size
) {
168 uptr page_size
= GetPageSizeCached();
169 // Checking too large memory ranges is slow.
170 CHECK_LT(size
, page_size
* 10);
175 internal_write(sock_pair
[1], reinterpret_cast<void *>(beg
), size
);
178 if (internal_iserror(bytes_written
, &write_errno
)) {
179 CHECK_EQ(EFAULT
, write_errno
);
182 result
= (bytes_written
== size
);
184 internal_close(sock_pair
[0]);
185 internal_close(sock_pair
[1]);
189 } // namespace __sanitizer
191 #endif // SANITIZER_POSIX