1 //=-- lsan_posix.cpp -----------------------------------------------------===//
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 LeakSanitizer.
10 // Standalone LSan RTL code common to POSIX-like systems.
12 //===---------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_platform.h"
18 #include "lsan_allocator.h"
19 #include "lsan_thread.h"
20 #include "sanitizer_common/sanitizer_stacktrace.h"
21 #include "sanitizer_common/sanitizer_tls_get_addr.h"
25 ThreadContext::ThreadContext(int tid
) : ThreadContextLsanBase(tid
) {}
27 struct OnStartedArgs
{
37 void ThreadContext::OnStarted(void *arg
) {
38 ThreadContextLsanBase::OnStarted(arg
);
39 auto args
= reinterpret_cast<const OnStartedArgs
*>(arg
);
40 stack_begin_
= args
->stack_begin
;
41 stack_end_
= args
->stack_end
;
42 tls_begin_
= args
->tls_begin
;
43 tls_end_
= args
->tls_end
;
44 cache_begin_
= args
->cache_begin
;
45 cache_end_
= args
->cache_end
;
49 void ThreadStart(u32 tid
, tid_t os_id
, ThreadType thread_type
) {
53 GetThreadStackAndTls(tid
== kMainTid
, &args
.stack_begin
, &stack_size
,
54 &args
.tls_begin
, &tls_size
);
55 args
.stack_end
= args
.stack_begin
+ stack_size
;
56 args
.tls_end
= args
.tls_begin
+ tls_size
;
57 GetAllocatorCacheRange(&args
.cache_begin
, &args
.cache_end
);
58 args
.dtls
= DTLS_Get();
59 ThreadContextLsanBase::ThreadStart(tid
, os_id
, thread_type
, &args
);
62 bool GetThreadRangesLocked(tid_t os_id
, uptr
*stack_begin
, uptr
*stack_end
,
63 uptr
*tls_begin
, uptr
*tls_end
, uptr
*cache_begin
,
64 uptr
*cache_end
, DTLS
**dtls
) {
65 ThreadContext
*context
= static_cast<ThreadContext
*>(
66 GetLsanThreadRegistryLocked()->FindThreadContextByOsIDLocked(os_id
));
69 *stack_begin
= context
->stack_begin();
70 *stack_end
= context
->stack_end();
71 *tls_begin
= context
->tls_begin();
72 *tls_end
= context
->tls_end();
73 *cache_begin
= context
->cache_begin();
74 *cache_end
= context
->cache_end();
75 *dtls
= context
->dtls();
79 void InitializeMainThread() {
80 u32 tid
= ThreadCreate(kMainTid
, true);
81 CHECK_EQ(tid
, kMainTid
);
82 ThreadStart(tid
, GetTid());
85 static void OnStackUnwind(const SignalContext
&sig
, const void *,
86 BufferedStackTrace
*stack
) {
87 stack
->Unwind(StackTrace::GetNextInstructionPc(sig
.pc
), sig
.bp
, sig
.context
,
88 common_flags()->fast_unwind_on_fatal
);
91 void LsanOnDeadlySignal(int signo
, void *siginfo
, void *context
) {
92 HandleDeadlySignal(siginfo
, context
, GetCurrentThreadId(), &OnStackUnwind
,
96 void InstallAtExitCheckLeaks() {
97 if (common_flags()->detect_leaks
&& common_flags()->leak_check_at_exit
)
101 } // namespace __lsan
103 #endif // SANITIZER_POSIX