asan_thread.h revision 1.1.1.1.8.2 1 1.1.1.1.8.2 tls //===-- asan_thread.h -------------------------------------------*- C++ -*-===//
2 1.1.1.1.8.2 tls //
3 1.1.1.1.8.2 tls // This file is distributed under the University of Illinois Open Source
4 1.1.1.1.8.2 tls // License. See LICENSE.TXT for details.
5 1.1.1.1.8.2 tls //
6 1.1.1.1.8.2 tls //===----------------------------------------------------------------------===//
7 1.1.1.1.8.2 tls //
8 1.1.1.1.8.2 tls // This file is a part of AddressSanitizer, an address sanity checker.
9 1.1.1.1.8.2 tls //
10 1.1.1.1.8.2 tls // ASan-private header for asan_thread.cc.
11 1.1.1.1.8.2 tls //===----------------------------------------------------------------------===//
12 1.1.1.1.8.2 tls #ifndef ASAN_THREAD_H
13 1.1.1.1.8.2 tls #define ASAN_THREAD_H
14 1.1.1.1.8.2 tls
15 1.1.1.1.8.2 tls #include "asan_allocator.h"
16 1.1.1.1.8.2 tls #include "asan_internal.h"
17 1.1.1.1.8.2 tls #include "asan_stack.h"
18 1.1.1.1.8.2 tls #include "asan_stats.h"
19 1.1.1.1.8.2 tls #include "sanitizer_common/sanitizer_libc.h"
20 1.1.1.1.8.2 tls
21 1.1.1.1.8.2 tls namespace __asan {
22 1.1.1.1.8.2 tls
23 1.1.1.1.8.2 tls const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits.
24 1.1.1.1.8.2 tls
25 1.1.1.1.8.2 tls class AsanThread;
26 1.1.1.1.8.2 tls
27 1.1.1.1.8.2 tls // These objects are created for every thread and are never deleted,
28 1.1.1.1.8.2 tls // so we can find them by tid even if the thread is long dead.
29 1.1.1.1.8.2 tls class AsanThreadSummary {
30 1.1.1.1.8.2 tls public:
31 1.1.1.1.8.2 tls explicit AsanThreadSummary(LinkerInitialized) { } // for T0.
32 1.1.1.1.8.2 tls void Init(u32 parent_tid, StackTrace *stack) {
33 1.1.1.1.8.2 tls parent_tid_ = parent_tid;
34 1.1.1.1.8.2 tls announced_ = false;
35 1.1.1.1.8.2 tls tid_ = kInvalidTid;
36 1.1.1.1.8.2 tls if (stack) {
37 1.1.1.1.8.2 tls internal_memcpy(&stack_, stack, sizeof(*stack));
38 1.1.1.1.8.2 tls }
39 1.1.1.1.8.2 tls thread_ = 0;
40 1.1.1.1.8.2 tls name_[0] = 0;
41 1.1.1.1.8.2 tls }
42 1.1.1.1.8.2 tls u32 tid() { return tid_; }
43 1.1.1.1.8.2 tls void set_tid(u32 tid) { tid_ = tid; }
44 1.1.1.1.8.2 tls u32 parent_tid() { return parent_tid_; }
45 1.1.1.1.8.2 tls bool announced() { return announced_; }
46 1.1.1.1.8.2 tls void set_announced(bool announced) { announced_ = announced; }
47 1.1.1.1.8.2 tls StackTrace *stack() { return &stack_; }
48 1.1.1.1.8.2 tls AsanThread *thread() { return thread_; }
49 1.1.1.1.8.2 tls void set_thread(AsanThread *thread) { thread_ = thread; }
50 1.1.1.1.8.2 tls static void TSDDtor(void *tsd);
51 1.1.1.1.8.2 tls void set_name(const char *name) {
52 1.1.1.1.8.2 tls internal_strncpy(name_, name, sizeof(name_) - 1);
53 1.1.1.1.8.2 tls }
54 1.1.1.1.8.2 tls const char *name() { return name_; }
55 1.1.1.1.8.2 tls
56 1.1.1.1.8.2 tls private:
57 1.1.1.1.8.2 tls u32 tid_;
58 1.1.1.1.8.2 tls u32 parent_tid_;
59 1.1.1.1.8.2 tls bool announced_;
60 1.1.1.1.8.2 tls StackTrace stack_;
61 1.1.1.1.8.2 tls AsanThread *thread_;
62 1.1.1.1.8.2 tls char name_[128];
63 1.1.1.1.8.2 tls };
64 1.1.1.1.8.2 tls
65 1.1.1.1.8.2 tls // AsanThreadSummary objects are never freed, so we need many of them.
66 1.1.1.1.8.2 tls COMPILER_CHECK(sizeof(AsanThreadSummary) <= 4094);
67 1.1.1.1.8.2 tls
68 1.1.1.1.8.2 tls // AsanThread are stored in TSD and destroyed when the thread dies.
69 1.1.1.1.8.2 tls class AsanThread {
70 1.1.1.1.8.2 tls public:
71 1.1.1.1.8.2 tls explicit AsanThread(LinkerInitialized); // for T0.
72 1.1.1.1.8.2 tls static AsanThread *Create(u32 parent_tid, thread_callback_t start_routine,
73 1.1.1.1.8.2 tls void *arg, StackTrace *stack);
74 1.1.1.1.8.2 tls void Destroy();
75 1.1.1.1.8.2 tls
76 1.1.1.1.8.2 tls void Init(); // Should be called from the thread itself.
77 1.1.1.1.8.2 tls thread_return_t ThreadStart();
78 1.1.1.1.8.2 tls
79 1.1.1.1.8.2 tls uptr stack_top() { return stack_top_; }
80 1.1.1.1.8.2 tls uptr stack_bottom() { return stack_bottom_; }
81 1.1.1.1.8.2 tls uptr stack_size() { return stack_top_ - stack_bottom_; }
82 1.1.1.1.8.2 tls u32 tid() { return summary_->tid(); }
83 1.1.1.1.8.2 tls AsanThreadSummary *summary() { return summary_; }
84 1.1.1.1.8.2 tls void set_summary(AsanThreadSummary *summary) { summary_ = summary; }
85 1.1.1.1.8.2 tls
86 1.1.1.1.8.2 tls const char *GetFrameNameByAddr(uptr addr, uptr *offset);
87 1.1.1.1.8.2 tls
88 1.1.1.1.8.2 tls bool AddrIsInStack(uptr addr) {
89 1.1.1.1.8.2 tls return addr >= stack_bottom_ && addr < stack_top_;
90 1.1.1.1.8.2 tls }
91 1.1.1.1.8.2 tls
92 1.1.1.1.8.2 tls FakeStack &fake_stack() { return fake_stack_; }
93 1.1.1.1.8.2 tls AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
94 1.1.1.1.8.2 tls AsanStats &stats() { return stats_; }
95 1.1.1.1.8.2 tls
96 1.1.1.1.8.2 tls private:
97 1.1.1.1.8.2 tls void SetThreadStackTopAndBottom();
98 1.1.1.1.8.2 tls void ClearShadowForThreadStack();
99 1.1.1.1.8.2 tls AsanThreadSummary *summary_;
100 1.1.1.1.8.2 tls thread_callback_t start_routine_;
101 1.1.1.1.8.2 tls void *arg_;
102 1.1.1.1.8.2 tls uptr stack_top_;
103 1.1.1.1.8.2 tls uptr stack_bottom_;
104 1.1.1.1.8.2 tls
105 1.1.1.1.8.2 tls FakeStack fake_stack_;
106 1.1.1.1.8.2 tls AsanThreadLocalMallocStorage malloc_storage_;
107 1.1.1.1.8.2 tls AsanStats stats_;
108 1.1.1.1.8.2 tls };
109 1.1.1.1.8.2 tls
110 1.1.1.1.8.2 tls } // namespace __asan
111 1.1.1.1.8.2 tls
112 1.1.1.1.8.2 tls #endif // ASAN_THREAD_H
113