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 ScopedDeadlySignal
signal_scope(GetCurrentThread());
35 uptr addr
= (uptr
)((siginfo_t
*)siginfo
)->si_addr
;
36 int code
= (int)((siginfo_t
*)siginfo
)->si_code
;
37 // Write the first message using the bullet-proof write.
38 if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
40 GetPcSpBp(context
, &pc
, &sp
, &bp
);
42 // Access at a reasonable offset above SP, or slightly below it (to account
43 // for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is
44 // probably a stack overflow.
45 // We also check si_code to filter out SEGV caused by something else other
46 // then hitting the guard page or unmapped memory, like, for example,
47 // unaligned memory access.
48 if (addr
+ 512 > sp
&& addr
< sp
+ 0xFFFF &&
49 (code
== si_SEGV_MAPERR
|| code
== si_SEGV_ACCERR
))
50 ReportStackOverflow(pc
, sp
, bp
, context
, addr
);
52 ReportSIGSEGV("SEGV", pc
, sp
, bp
, context
, addr
);
55 // ---------------------- TSD ---------------- {{{1
57 static pthread_key_t tsd_key
;
58 static bool tsd_key_inited
= false;
59 void AsanTSDInit(void (*destructor
)(void *tsd
)) {
60 CHECK(!tsd_key_inited
);
61 tsd_key_inited
= true;
62 CHECK_EQ(0, pthread_key_create(&tsd_key
, destructor
));
66 CHECK(tsd_key_inited
);
67 return pthread_getspecific(tsd_key
);
70 void AsanTSDSet(void *tsd
) {
71 CHECK(tsd_key_inited
);
72 pthread_setspecific(tsd_key
, tsd
);
75 void PlatformTSDDtor(void *tsd
) {
76 AsanThreadContext
*context
= (AsanThreadContext
*)tsd
;
77 if (context
->destructor_iterations
> 1) {
78 context
->destructor_iterations
--;
79 CHECK_EQ(0, pthread_setspecific(tsd_key
, tsd
));
82 AsanThread::TSDDtor(tsd
);
86 #endif // SANITIZER_POSIX