asan_posix.cc revision e1fe0fd868886b53cb8d5d957afebbdd47688df7
1//===-- asan_linux.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 a part of AddressSanitizer, an address sanity checker. 11// 12// Posix-specific details. 13//===----------------------------------------------------------------------===// 14#if defined(__linux__) || defined(__APPLE__) 15 16#include "asan_internal.h" 17#include "asan_interceptors.h" 18#include "asan_stack.h" 19#include "asan_thread_registry.h" 20 21#include <pthread.h> 22#include <signal.h> 23#include <sys/time.h> 24#include <sys/resource.h> 25#include <unistd.h> 26 27#ifdef ANDROID 28#include <sys/atomics.h> 29#endif 30 31namespace __asan { 32 33static void MaybeInstallSigaction(int signum, 34 void (*handler)(int, siginfo_t *, void *)) { 35 if (!AsanInterceptsSignal(signum)) 36 return; 37 struct sigaction sigact; 38 REAL(memset)(&sigact, 0, sizeof(sigact)); 39 sigact.sa_sigaction = handler; 40 sigact.sa_flags = SA_SIGINFO; 41 CHECK(0 == REAL(sigaction)(signum, &sigact, 0)); 42} 43 44static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { 45 uintptr_t addr = (uintptr_t)siginfo->si_addr; 46 // Write the first message using the bullet-proof write. 47 if (13 != AsanWrite(2, "ASAN:SIGSEGV\n", 13)) AsanDie(); 48 uintptr_t pc, sp, bp; 49 GetPcSpBp(context, &pc, &sp, &bp); 50 Report("ERROR: AddressSanitizer crashed on unknown address %p" 51 " (pc %p sp %p bp %p T%d)\n", 52 addr, pc, sp, bp, 53 asanThreadRegistry().GetCurrentTidOrMinusOne()); 54 Printf("AddressSanitizer can not provide additional info. ABORTING\n"); 55 GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); 56 stack.PrintStack(); 57 ShowStatsAndAbort(); 58} 59 60void InstallSignalHandlers() { 61 MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV); 62 MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV); 63} 64 65void AsanDisableCoreDumper() { 66 struct rlimit nocore; 67 nocore.rlim_cur = 0; 68 nocore.rlim_max = 0; 69 setrlimit(RLIMIT_CORE, &nocore); 70} 71 72int GetPid() { 73 return getpid(); 74} 75 76uintptr_t GetThreadSelf() { 77 return (uintptr_t)pthread_self(); 78} 79 80void SleepForSeconds(int seconds) { 81 sleep(seconds); 82} 83 84void Exit(int exitcode) { 85 return _exit(exitcode); 86} 87 88int AtomicInc(int *a) { 89#ifdef ANDROID 90 return __atomic_inc(a) + 1; 91#else 92 return __sync_add_and_fetch(a, 1); 93#endif 94} 95 96// ---------------------- TSD ---------------- {{{1 97 98static pthread_key_t tsd_key; 99static bool tsd_key_inited = false; 100void AsanTSDInit(void (*destructor)(void *tsd)) { 101 CHECK(!tsd_key_inited); 102 tsd_key_inited = true; 103 CHECK(0 == pthread_key_create(&tsd_key, destructor)); 104} 105 106void *AsanTSDGet() { 107 CHECK(tsd_key_inited); 108 return pthread_getspecific(tsd_key); 109} 110 111void AsanTSDSet(void *tsd) { 112 CHECK(tsd_key_inited); 113 pthread_setspecific(tsd_key, tsd); 114} 115 116} // namespace __asan 117 118#endif // __linux__ || __APPLE_ 119