master
  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