sanitizer_posix_libcdep.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1//===-- sanitizer_posix_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// 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//===----------------------------------------------------------------------===// 14 15#include "sanitizer_platform.h" 16 17#if SANITIZER_POSIX 18#include "sanitizer_common.h" 19#include "sanitizer_flags.h" 20#include "sanitizer_platform_limits_posix.h" 21#include "sanitizer_stacktrace.h" 22 23#include <errno.h> 24#include <pthread.h> 25#include <signal.h> 26#include <stdlib.h> 27#include <sys/mman.h> 28#include <sys/resource.h> 29#include <sys/time.h> 30#include <sys/types.h> 31#include <unistd.h> 32 33namespace __sanitizer { 34 35u32 GetUid() { 36 return getuid(); 37} 38 39uptr GetThreadSelf() { 40 return (uptr)pthread_self(); 41} 42 43void FlushUnneededShadowMemory(uptr addr, uptr size) { 44 madvise((void*)addr, size, MADV_DONTNEED); 45} 46 47void DisableCoreDumper() { 48 struct rlimit nocore; 49 nocore.rlim_cur = 0; 50 nocore.rlim_max = 0; 51 setrlimit(RLIMIT_CORE, &nocore); 52} 53 54bool StackSizeIsUnlimited() { 55 struct rlimit rlim; 56 CHECK_EQ(0, getrlimit(RLIMIT_STACK, &rlim)); 57 return ((uptr)rlim.rlim_cur == (uptr)-1); 58} 59 60void SetStackSizeLimitInBytes(uptr limit) { 61 struct rlimit rlim; 62 rlim.rlim_cur = limit; 63 rlim.rlim_max = limit; 64 if (setrlimit(RLIMIT_STACK, &rlim)) { 65 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno); 66 Die(); 67 } 68 CHECK(!StackSizeIsUnlimited()); 69} 70 71void SleepForSeconds(int seconds) { 72 sleep(seconds); 73} 74 75void SleepForMillis(int millis) { 76 usleep(millis * 1000); 77} 78 79void Abort() { 80 abort(); 81} 82 83int Atexit(void (*function)(void)) { 84#ifndef SANITIZER_GO 85 return atexit(function); 86#else 87 return 0; 88#endif 89} 90 91int internal_isatty(fd_t fd) { 92 return isatty(fd); 93} 94 95#ifndef SANITIZER_GO 96// TODO(glider): different tools may require different altstack size. 97static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough. 98 99void SetAlternateSignalStack() { 100 stack_t altstack, oldstack; 101 CHECK_EQ(0, sigaltstack(0, &oldstack)); 102 // If the alternate stack is already in place, do nothing. 103 // Android always sets an alternate stack, but it's too small for us. 104 if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return; 105 // TODO(glider): the mapped stack should have the MAP_STACK flag in the 106 // future. It is not required by man 2 sigaltstack now (they're using 107 // malloc()). 108 void* base = MmapOrDie(kAltStackSize, __func__); 109 altstack.ss_sp = (char*) base; 110 altstack.ss_flags = 0; 111 altstack.ss_size = kAltStackSize; 112 CHECK_EQ(0, sigaltstack(&altstack, 0)); 113} 114 115void UnsetAlternateSignalStack() { 116 stack_t altstack, oldstack; 117 altstack.ss_sp = 0; 118 altstack.ss_flags = SS_DISABLE; 119 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin. 120 CHECK_EQ(0, sigaltstack(&altstack, &oldstack)); 121 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size); 122} 123 124typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 125static void MaybeInstallSigaction(int signum, 126 SignalHandlerType handler) { 127 if (!IsDeadlySignal(signum)) 128 return; 129 struct sigaction sigact; 130 internal_memset(&sigact, 0, sizeof(sigact)); 131 sigact.sa_sigaction = (sa_sigaction_t)handler; 132 sigact.sa_flags = SA_SIGINFO; 133 if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK; 134 CHECK_EQ(0, internal_sigaction(signum, &sigact, 0)); 135 VReport(1, "Installed the sigaction for signal %d\n", signum); 136} 137 138void InstallDeadlySignalHandlers(SignalHandlerType handler) { 139 // Set the alternate signal stack for the main thread. 140 // This will cause SetAlternateSignalStack to be called twice, but the stack 141 // will be actually set only once. 142 if (common_flags()->use_sigaltstack) SetAlternateSignalStack(); 143 MaybeInstallSigaction(SIGSEGV, handler); 144 MaybeInstallSigaction(SIGBUS, handler); 145} 146#endif // SANITIZER_GO 147 148} // namespace __sanitizer 149 150#endif // SANITIZER_POSIX 151