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