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 };
39 
40 struct ReportStack {
41   SymbolizedStack *frames;
42   bool suppressable;
43   static ReportStack *New();
44 
45  private:
46   ReportStack();
47 };
48 
49 struct ReportMopMutex {
50   u64 id;
51   bool write;
52 };
53 
54 struct ReportMop {
55   int tid;
56   uptr addr;
57   int size;
58   bool write;
59   bool atomic;
60   uptr external_tag;
61   Vector<ReportMopMutex> mset;
62   ReportStack *stack;
63 
64   ReportMop();
65 };
66 
67 enum ReportLocationType {
68   ReportLocationGlobal,
69   ReportLocationHeap,
70   ReportLocationStack,
71   ReportLocationTLS,
72   ReportLocationFD
73 };
74 
75 struct ReportLocation {
76   ReportLocationType type;
77   DataInfo global;
78   uptr heap_chunk_start;
79   uptr heap_chunk_size;
80   uptr external_tag;
81   int tid;
82   int fd;
83   bool suppressable;
84   ReportStack *stack;
85 
86   static ReportLocation *New(ReportLocationType type);
87  private:
88   explicit ReportLocation(ReportLocationType type);
89 };
90 
91 struct ReportThread {
92   int id;
93   tid_t os_id;
94   bool running;
95   ThreadType thread_type;
96   char *name;
97   u32 parent_tid;
98   ReportStack *stack;
99 };
100 
101 struct ReportMutex {
102   u64 id;
103   uptr addr;
104   bool destroyed;
105   ReportStack *stack;
106 };
107 
108 class ReportDesc {
109  public:
110   ReportType typ;
111   uptr tag;
112   Vector<ReportStack*> stacks;
113   Vector<ReportMop*> mops;
114   Vector<ReportLocation*> locs;
115   Vector<ReportMutex*> mutexes;
116   Vector<ReportThread*> threads;
117   Vector<int> unique_tids;
118   ReportStack *sleep;
119   int count;
120 
121   ReportDesc();
122   ~ReportDesc();
123 
124  private:
125   ReportDesc(const ReportDesc&);
126   void operator = (const ReportDesc&);
127 };
128 
129 // Format and output the report to the console/log. No additional logic.
130 void PrintReport(const ReportDesc *rep);
131 void PrintStack(const ReportStack *stack);
132 
133 }  // namespace __tsan
134 
135 #endif  // TSAN_REPORT_H
136