13cab2bb3Spatrick //===-- tsan_report.h -------------------------------------------*- C++ -*-===// 23cab2bb3Spatrick // 33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information. 53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63cab2bb3Spatrick // 73cab2bb3Spatrick //===----------------------------------------------------------------------===// 83cab2bb3Spatrick // 93cab2bb3Spatrick // This file is a part of ThreadSanitizer (TSan), a race detector. 103cab2bb3Spatrick // 113cab2bb3Spatrick //===----------------------------------------------------------------------===// 123cab2bb3Spatrick #ifndef TSAN_REPORT_H 133cab2bb3Spatrick #define TSAN_REPORT_H 143cab2bb3Spatrick 153cab2bb3Spatrick #include "sanitizer_common/sanitizer_symbolizer.h" 163cab2bb3Spatrick #include "sanitizer_common/sanitizer_thread_registry.h" 173cab2bb3Spatrick #include "sanitizer_common/sanitizer_vector.h" 183cab2bb3Spatrick #include "tsan_defs.h" 193cab2bb3Spatrick 203cab2bb3Spatrick namespace __tsan { 213cab2bb3Spatrick 223cab2bb3Spatrick enum ReportType { 233cab2bb3Spatrick ReportTypeRace, 243cab2bb3Spatrick ReportTypeVptrRace, 253cab2bb3Spatrick ReportTypeUseAfterFree, 263cab2bb3Spatrick ReportTypeVptrUseAfterFree, 273cab2bb3Spatrick ReportTypeExternalRace, 283cab2bb3Spatrick ReportTypeThreadLeak, 293cab2bb3Spatrick ReportTypeMutexDestroyLocked, 303cab2bb3Spatrick ReportTypeMutexDoubleLock, 313cab2bb3Spatrick ReportTypeMutexInvalidAccess, 323cab2bb3Spatrick ReportTypeMutexBadUnlock, 333cab2bb3Spatrick ReportTypeMutexBadReadLock, 343cab2bb3Spatrick ReportTypeMutexBadReadUnlock, 353cab2bb3Spatrick ReportTypeSignalUnsafe, 363cab2bb3Spatrick ReportTypeErrnoInSignal, 373cab2bb3Spatrick ReportTypeDeadlock 383cab2bb3Spatrick }; 393cab2bb3Spatrick 403cab2bb3Spatrick struct ReportStack { 41*810390e3Srobert SymbolizedStack *frames = nullptr; 42*810390e3Srobert bool suppressable = false; 433cab2bb3Spatrick }; 443cab2bb3Spatrick 453cab2bb3Spatrick struct ReportMopMutex { 46*810390e3Srobert int id; 473cab2bb3Spatrick bool write; 483cab2bb3Spatrick }; 493cab2bb3Spatrick 503cab2bb3Spatrick struct ReportMop { 513cab2bb3Spatrick int tid; 523cab2bb3Spatrick uptr addr; 533cab2bb3Spatrick int size; 543cab2bb3Spatrick bool write; 553cab2bb3Spatrick bool atomic; 563cab2bb3Spatrick uptr external_tag; 573cab2bb3Spatrick Vector<ReportMopMutex> mset; 583cab2bb3Spatrick ReportStack *stack; 593cab2bb3Spatrick 603cab2bb3Spatrick ReportMop(); 613cab2bb3Spatrick }; 623cab2bb3Spatrick 633cab2bb3Spatrick enum ReportLocationType { 643cab2bb3Spatrick ReportLocationGlobal, 653cab2bb3Spatrick ReportLocationHeap, 663cab2bb3Spatrick ReportLocationStack, 673cab2bb3Spatrick ReportLocationTLS, 683cab2bb3Spatrick ReportLocationFD 693cab2bb3Spatrick }; 703cab2bb3Spatrick 713cab2bb3Spatrick struct ReportLocation { 72*810390e3Srobert ReportLocationType type = ReportLocationGlobal; 73*810390e3Srobert DataInfo global = {}; 74*810390e3Srobert uptr heap_chunk_start = 0; 75*810390e3Srobert uptr heap_chunk_size = 0; 76*810390e3Srobert uptr external_tag = 0; 77*810390e3Srobert Tid tid = kInvalidTid; 78*810390e3Srobert int fd = 0; 79*810390e3Srobert bool fd_closed = false; 80*810390e3Srobert bool suppressable = false; 81*810390e3Srobert ReportStack *stack = nullptr; 823cab2bb3Spatrick }; 833cab2bb3Spatrick 843cab2bb3Spatrick struct ReportThread { 85*810390e3Srobert Tid id; 863cab2bb3Spatrick tid_t os_id; 873cab2bb3Spatrick bool running; 883cab2bb3Spatrick ThreadType thread_type; 893cab2bb3Spatrick char *name; 90*810390e3Srobert Tid parent_tid; 913cab2bb3Spatrick ReportStack *stack; 923cab2bb3Spatrick }; 933cab2bb3Spatrick 943cab2bb3Spatrick struct ReportMutex { 95*810390e3Srobert int id; 963cab2bb3Spatrick uptr addr; 973cab2bb3Spatrick ReportStack *stack; 983cab2bb3Spatrick }; 993cab2bb3Spatrick 1003cab2bb3Spatrick class ReportDesc { 1013cab2bb3Spatrick public: 1023cab2bb3Spatrick ReportType typ; 1033cab2bb3Spatrick uptr tag; 1043cab2bb3Spatrick Vector<ReportStack*> stacks; 1053cab2bb3Spatrick Vector<ReportMop*> mops; 1063cab2bb3Spatrick Vector<ReportLocation*> locs; 1073cab2bb3Spatrick Vector<ReportMutex*> mutexes; 1083cab2bb3Spatrick Vector<ReportThread*> threads; 109*810390e3Srobert Vector<Tid> unique_tids; 1103cab2bb3Spatrick ReportStack *sleep; 1113cab2bb3Spatrick int count; 112*810390e3Srobert int signum = 0; 1133cab2bb3Spatrick 1143cab2bb3Spatrick ReportDesc(); 1153cab2bb3Spatrick ~ReportDesc(); 1163cab2bb3Spatrick 1173cab2bb3Spatrick private: 1183cab2bb3Spatrick ReportDesc(const ReportDesc&); 1193cab2bb3Spatrick void operator = (const ReportDesc&); 1203cab2bb3Spatrick }; 1213cab2bb3Spatrick 1223cab2bb3Spatrick // Format and output the report to the console/log. No additional logic. 1233cab2bb3Spatrick void PrintReport(const ReportDesc *rep); 1243cab2bb3Spatrick void PrintStack(const ReportStack *stack); 1253cab2bb3Spatrick 1263cab2bb3Spatrick } // namespace __tsan 1273cab2bb3Spatrick 1283cab2bb3Spatrick #endif // TSAN_REPORT_H 129