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