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};
39
40struct ReportStack {
41  SymbolizedStack *frames;
42  bool suppressable;
43  static ReportStack *New();
44
45 private:
46  ReportStack();
47};
48
49struct ReportMopMutex {
50  u64 id;
51  bool write;
52};
53
54struct 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
67enum ReportLocationType {
68  ReportLocationGlobal,
69  ReportLocationHeap,
70  ReportLocationStack,
71  ReportLocationTLS,
72  ReportLocationFD
73};
74
75struct 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
91struct 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
101struct ReportMutex {
102  u64 id;
103  uptr addr;
104  bool destroyed;
105  ReportStack *stack;
106};
107
108class 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.
130void PrintReport(const ReportDesc *rep);
131void PrintStack(const ReportStack *stack);
132
133}  // namespace __tsan
134
135#endif  // TSAN_REPORT_H
136