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