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