]>
Commit | Line | Data |
---|---|---|
3c6331c2 ML |
1 | //=-- lsan_posix.cpp -----------------------------------------------------===// |
2 | // | |
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 | |
6 | // | |
7 | //===---------------------------------------------------------------------===// | |
8 | // | |
9 | // This file is a part of LeakSanitizer. | |
10 | // Standalone LSan RTL code common to POSIX-like systems. | |
11 | // | |
12 | //===---------------------------------------------------------------------===// | |
13 | ||
14 | #include "sanitizer_common/sanitizer_platform.h" | |
15 | ||
16 | #if SANITIZER_POSIX | |
17 | #include "lsan.h" | |
18 | #include "lsan_allocator.h" | |
19 | #include "sanitizer_common/sanitizer_stacktrace.h" | |
20 | #include "sanitizer_common/sanitizer_tls_get_addr.h" | |
21 | ||
22 | namespace __lsan { | |
23 | ||
24 | ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {} | |
25 | ||
26 | struct OnStartedArgs { | |
27 | uptr stack_begin; | |
28 | uptr stack_end; | |
29 | uptr cache_begin; | |
30 | uptr cache_end; | |
31 | uptr tls_begin; | |
32 | uptr tls_end; | |
33 | DTLS *dtls; | |
34 | }; | |
35 | ||
36 | void ThreadContext::OnStarted(void *arg) { | |
37 | auto args = reinterpret_cast<const OnStartedArgs *>(arg); | |
38 | stack_begin_ = args->stack_begin; | |
39 | stack_end_ = args->stack_end; | |
40 | tls_begin_ = args->tls_begin; | |
41 | tls_end_ = args->tls_end; | |
42 | cache_begin_ = args->cache_begin; | |
43 | cache_end_ = args->cache_end; | |
44 | dtls_ = args->dtls; | |
45 | } | |
46 | ||
47 | void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) { | |
48 | OnStartedArgs args; | |
49 | uptr stack_size = 0; | |
50 | uptr tls_size = 0; | |
51 | GetThreadStackAndTls(tid == 0, &args.stack_begin, &stack_size, | |
52 | &args.tls_begin, &tls_size); | |
53 | args.stack_end = args.stack_begin + stack_size; | |
54 | args.tls_end = args.tls_begin + tls_size; | |
55 | GetAllocatorCacheRange(&args.cache_begin, &args.cache_end); | |
56 | args.dtls = DTLS_Get(); | |
57 | ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args); | |
58 | } | |
59 | ||
60 | bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, | |
61 | uptr *tls_begin, uptr *tls_end, uptr *cache_begin, | |
62 | uptr *cache_end, DTLS **dtls) { | |
63 | ThreadContext *context = static_cast<ThreadContext *>( | |
64 | GetThreadRegistryLocked()->FindThreadContextByOsIDLocked(os_id)); | |
65 | if (!context) | |
66 | return false; | |
67 | *stack_begin = context->stack_begin(); | |
68 | *stack_end = context->stack_end(); | |
69 | *tls_begin = context->tls_begin(); | |
70 | *tls_end = context->tls_end(); | |
71 | *cache_begin = context->cache_begin(); | |
72 | *cache_end = context->cache_end(); | |
73 | *dtls = context->dtls(); | |
74 | return true; | |
75 | } | |
76 | ||
77 | void InitializeMainThread() { | |
78 | u32 tid = ThreadCreate(0, 0, true); | |
79 | CHECK_EQ(tid, 0); | |
80 | ThreadStart(tid, GetTid()); | |
81 | } | |
82 | ||
83 | static void OnStackUnwind(const SignalContext &sig, const void *, | |
84 | BufferedStackTrace *stack) { | |
85 | stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, | |
86 | common_flags()->fast_unwind_on_fatal); | |
87 | } | |
88 | ||
89 | void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { | |
90 | HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind, | |
91 | nullptr); | |
92 | } | |
93 | ||
94 | } // namespace __lsan | |
95 | ||
96 | #endif // SANITIZER_POSIX |