1 | //===-- tsan_report.h -------------------------------------------*- C++ -*-===// |
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 ThreadSanitizer (TSan), a race detector. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | #ifndef TSAN_REPORT_H |
13 | #define TSAN_REPORT_H |
14 | |
15 | #include "sanitizer_common/sanitizer_symbolizer.h" |
16 | #include "sanitizer_common/sanitizer_thread_registry.h" |
17 | #include "sanitizer_common/sanitizer_vector.h" |
18 | #include "tsan_defs.h" |
19 | |
20 | namespace __tsan { |
21 | |
22 | enum ReportType { |
23 | ReportTypeRace, |
24 | ReportTypeVptrRace, |
25 | ReportTypeUseAfterFree, |
26 | ReportTypeVptrUseAfterFree, |
27 | ReportTypeExternalRace, |
28 | ReportTypeThreadLeak, |
29 | ReportTypeMutexDestroyLocked, |
30 | ReportTypeMutexDoubleLock, |
31 | ReportTypeMutexInvalidAccess, |
32 | ReportTypeMutexBadUnlock, |
33 | ReportTypeMutexBadReadLock, |
34 | ReportTypeMutexBadReadUnlock, |
35 | ReportTypeSignalUnsafe, |
36 | ReportTypeErrnoInSignal, |
37 | ReportTypeDeadlock, |
38 | ReportTypeMutexHeldWrongContext |
39 | }; |
40 | |
41 | struct ReportStack { |
42 | SymbolizedStack *frames = nullptr; |
43 | bool suppressable = false; |
44 | }; |
45 | |
46 | struct ReportMopMutex { |
47 | int id; |
48 | bool write; |
49 | }; |
50 | |
51 | struct ReportMop { |
52 | int tid; |
53 | uptr addr; |
54 | int size; |
55 | bool write; |
56 | bool atomic; |
57 | uptr external_tag; |
58 | Vector<ReportMopMutex> mset; |
59 | ReportStack *stack; |
60 | |
61 | ReportMop(); |
62 | }; |
63 | |
64 | enum ReportLocationType { |
65 | ReportLocationGlobal, |
66 | ReportLocationHeap, |
67 | ReportLocationStack, |
68 | ReportLocationTLS, |
69 | ReportLocationFD |
70 | }; |
71 | |
72 | struct ReportLocation { |
73 | ReportLocationType type = ReportLocationGlobal; |
74 | DataInfo global = {}; |
75 | uptr heap_chunk_start = 0; |
76 | uptr heap_chunk_size = 0; |
77 | uptr external_tag = 0; |
78 | Tid tid = kInvalidTid; |
79 | int fd = 0; |
80 | bool fd_closed = false; |
81 | bool suppressable = false; |
82 | ReportStack *stack = nullptr; |
83 | }; |
84 | |
85 | struct ReportThread { |
86 | Tid id; |
87 | tid_t os_id; |
88 | bool running; |
89 | ThreadType thread_type; |
90 | char *name; |
91 | Tid parent_tid; |
92 | ReportStack *stack; |
93 | }; |
94 | |
95 | struct ReportMutex { |
96 | int id; |
97 | uptr addr; |
98 | ReportStack *stack; |
99 | }; |
100 | |
101 | class ReportDesc { |
102 | public: |
103 | ReportType typ; |
104 | uptr tag; |
105 | Vector<ReportStack*> stacks; |
106 | Vector<ReportMop*> mops; |
107 | Vector<ReportLocation*> locs; |
108 | Vector<ReportMutex*> mutexes; |
109 | Vector<ReportThread*> threads; |
110 | Vector<Tid> unique_tids; |
111 | ReportStack *sleep; |
112 | int count; |
113 | int signum = 0; |
114 | |
115 | ReportDesc(); |
116 | ~ReportDesc(); |
117 | |
118 | private: |
119 | ReportDesc(const ReportDesc&); |
120 | void operator = (const ReportDesc&); |
121 | }; |
122 | |
123 | // Format and output the report to the console/log. No additional logic. |
124 | void PrintReport(const ReportDesc *rep); |
125 | void PrintStack(const ReportStack *stack); |
126 | |
127 | } // namespace __tsan |
128 | |
129 | #endif // TSAN_REPORT_H |
130 | |