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 fd_closed = false; 80 bool suppressable = false; 81 ReportStack *stack = nullptr; 82 }; 83 84 struct ReportThread { 85 Tid id; 86 tid_t os_id; 87 bool running; 88 ThreadType thread_type; 89 char *name; 90 Tid parent_tid; 91 ReportStack *stack; 92 }; 93 94 struct ReportMutex { 95 int id; 96 uptr addr; 97 ReportStack *stack; 98 }; 99 100 class ReportDesc { 101 public: 102 ReportType typ; 103 uptr tag; 104 Vector<ReportStack*> stacks; 105 Vector<ReportMop*> mops; 106 Vector<ReportLocation*> locs; 107 Vector<ReportMutex*> mutexes; 108 Vector<ReportThread*> threads; 109 Vector<Tid> unique_tids; 110 ReportStack *sleep; 111 int count; 112 int signum = 0; 113 114 ReportDesc(); 115 ~ReportDesc(); 116 117 private: 118 ReportDesc(const ReportDesc&); 119 void operator = (const ReportDesc&); 120 }; 121 122 // Format and output the report to the console/log. No additional logic. 123 void PrintReport(const ReportDesc *rep); 124 void PrintStack(const ReportStack *stack); 125 126 } // namespace __tsan 127 128 #endif // TSAN_REPORT_H 129