1 //===-- asan_posix.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 a part of AddressSanitizer, an address sanity checker.
12 // Posix-specific details.
13 //===----------------------------------------------------------------------===//
15 #include "sanitizer_common/sanitizer_platform.h"
18 #include "asan_internal.h"
19 #include "asan_interceptors.h"
20 #include "asan_mapping.h"
21 #include "asan_report.h"
22 #include "asan_stack.h"
23 #include "sanitizer_common/sanitizer_libc.h"
24 #include "sanitizer_common/sanitizer_procmaps.h"
30 #include <sys/resource.h>
35 void AsanOnSIGSEGV(int, void *siginfo
, void *context
) {
36 uptr addr
= (uptr
)((siginfo_t
*)siginfo
)->si_addr
;
37 int code
= (int)((siginfo_t
*)siginfo
)->si_code
;
38 // Write the first message using the bullet-proof write.
39 if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
41 GetPcSpBp(context
, &pc
, &sp
, &bp
);
43 // Access at a reasonable offset above SP, or slightly below it (to account
44 // for x86_64 redzone, ARM push of multiple registers, etc) is probably a
46 // We also check si_code to filter out SEGV caused by something else other
47 // then hitting the guard page or unmapped memory, like, for example,
48 // unaligned memory access.
49 if (addr
+ 128 > sp
&& addr
< sp
+ 0xFFFF &&
50 (code
== si_SEGV_MAPERR
|| code
== si_SEGV_ACCERR
))
51 ReportStackOverflow(pc
, sp
, bp
, context
, addr
);
53 ReportSIGSEGV("SEGV", pc
, sp
, bp
, context
, addr
);
56 // ---------------------- TSD ---------------- {{{1
58 static pthread_key_t tsd_key
;
59 static bool tsd_key_inited
= false;
60 void AsanTSDInit(void (*destructor
)(void *tsd
)) {
61 CHECK(!tsd_key_inited
);
62 tsd_key_inited
= true;
63 CHECK_EQ(0, pthread_key_create(&tsd_key
, destructor
));
67 CHECK(tsd_key_inited
);
68 return pthread_getspecific(tsd_key
);
71 void AsanTSDSet(void *tsd
) {
72 CHECK(tsd_key_inited
);
73 pthread_setspecific(tsd_key
, tsd
);
76 void PlatformTSDDtor(void *tsd
) {
77 AsanThreadContext
*context
= (AsanThreadContext
*)tsd
;
78 if (context
->destructor_iterations
> 1) {
79 context
->destructor_iterations
--;
80 CHECK_EQ(0, pthread_setspecific(tsd_key
, tsd
));
83 AsanThread::TSDDtor(tsd
);
87 #endif // SANITIZER_POSIX