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