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
20namespace __tsan {
21
22enum 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
41struct ReportStack {
42  SymbolizedStack *frames = nullptr;
43  bool suppressable = false;
44};
45
46struct ReportMopMutex {
47  int id;
48  bool write;
49};
50
51struct 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
64enum ReportLocationType {
65  ReportLocationGlobal,
66  ReportLocationHeap,
67  ReportLocationStack,
68  ReportLocationTLS,
69  ReportLocationFD
70};
71
72struct 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
85struct 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
95struct ReportMutex {
96  int id;
97  uptr addr;
98  ReportStack *stack;
99};
100
101class 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.
124void PrintReport(const ReportDesc *rep);
125void PrintStack(const ReportStack *stack);
126
127}  // namespace __tsan
128
129#endif  // TSAN_REPORT_H
130