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