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