xref: /openbsd-src/gnu/llvm/compiler-rt/lib/tsan/rtl/tsan_report.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
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