1 //===-- asan_posix.cc -----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of AddressSanitizer, an address sanity checker.
11 // Posix-specific details.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_platform.h"
17 #include "asan_internal.h"
18 #include "asan_interceptors.h"
19 #include "asan_mapping.h"
20 #include "asan_report.h"
21 #include "asan_stack.h"
22 #include "sanitizer_common/sanitizer_libc.h"
23 #include "sanitizer_common/sanitizer_posix.h"
24 #include "sanitizer_common/sanitizer_procmaps.h"
29 #include <sys/resource.h>
34 void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
35 StartReportDeadlySignal();
36 SignalContext sig(siginfo, context);
37 ReportDeadlySignal(sig);
40 // ---------------------- TSD ---------------- {{{1
42 #if SANITIZER_NETBSD && !ASAN_DYNAMIC
43 // Thread Static Data cannot be used in early static ASan init on NetBSD.
44 // Reuse the Asan TSD API for compatibility with existing code
45 // with an alternative implementation.
47 static void (*tsd_destructor)(void *tsd) = nullptr;
50 tsd_key() : key(nullptr) {}
52 CHECK(tsd_destructor);
54 (*tsd_destructor)(key);
59 static thread_local struct tsd_key key;
61 void AsanTSDInit(void (*destructor)(void *tsd)) {
62 CHECK(!tsd_destructor);
63 tsd_destructor = destructor;
67 CHECK(tsd_destructor);
71 void AsanTSDSet(void *tsd) {
72 CHECK(tsd_destructor);
78 void PlatformTSDDtor(void *tsd) {
79 CHECK(tsd_destructor);
80 CHECK_EQ(key.key, tsd);
82 // Make sure that signal handler can not see a stale current thread pointer.
83 atomic_signal_fence(memory_order_seq_cst);
84 AsanThread::TSDDtor(tsd);
87 static pthread_key_t tsd_key;
88 static bool tsd_key_inited = false;
89 void AsanTSDInit(void (*destructor)(void *tsd)) {
90 CHECK(!tsd_key_inited);
91 tsd_key_inited = true;
92 CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
96 CHECK(tsd_key_inited);
97 return pthread_getspecific(tsd_key);
100 void AsanTSDSet(void *tsd) {
101 CHECK(tsd_key_inited);
102 pthread_setspecific(tsd_key, tsd);
105 void PlatformTSDDtor(void *tsd) {
106 AsanThreadContext *context = (AsanThreadContext*)tsd;
107 if (context->destructor_iterations > 1) {
108 context->destructor_iterations--;
109 CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
112 AsanThread::TSDDtor(tsd);
115 } // namespace __asan
117 #endif // SANITIZER_POSIX