PR go/67101
[official-gcc.git] / libsanitizer / tsan / tsan_symbolize.cc
blob795f838991b63e92041d1fabbc6795787581e4f9
1 //===-- tsan_symbolize.cc -------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
9 //
10 //===----------------------------------------------------------------------===//
12 #include "tsan_symbolize.h"
14 #include "sanitizer_common/sanitizer_common.h"
15 #include "sanitizer_common/sanitizer_placement_new.h"
16 #include "sanitizer_common/sanitizer_symbolizer.h"
17 #include "tsan_flags.h"
18 #include "tsan_report.h"
19 #include "tsan_rtl.h"
21 namespace __tsan {
23 void EnterSymbolizer() {
24 ThreadState *thr = cur_thread();
25 CHECK(!thr->in_symbolizer);
26 thr->in_symbolizer = true;
27 thr->ignore_interceptors++;
30 void ExitSymbolizer() {
31 ThreadState *thr = cur_thread();
32 CHECK(thr->in_symbolizer);
33 thr->in_symbolizer = false;
34 thr->ignore_interceptors--;
37 // Denotes fake PC values that come from JIT/JAVA/etc.
38 // For such PC values __tsan_symbolize_external() will be called.
39 const uptr kExternalPCBit = 1ULL << 60;
41 // May be overriden by JIT/JAVA/etc,
42 // whatever produces PCs marked with kExternalPCBit.
43 extern "C" bool __tsan_symbolize_external(uptr pc,
44 char *func_buf, uptr func_siz,
45 char *file_buf, uptr file_siz,
46 int *line, int *col)
47 SANITIZER_WEAK_ATTRIBUTE;
49 bool __tsan_symbolize_external(uptr pc,
50 char *func_buf, uptr func_siz,
51 char *file_buf, uptr file_siz,
52 int *line, int *col) {
53 return false;
56 ReportStack *SymbolizeCode(uptr addr) {
57 // Check if PC comes from non-native land.
58 if (addr & kExternalPCBit) {
59 // Declare static to not consume too much stack space.
60 // We symbolize reports in a single thread, so this is fine.
61 static char func_buf[1024];
62 static char file_buf[1024];
63 int line, col;
64 ReportStack *ent = ReportStack::New(addr);
65 if (!__tsan_symbolize_external(addr, func_buf, sizeof(func_buf),
66 file_buf, sizeof(file_buf), &line, &col))
67 return ent;
68 ent->info.function = internal_strdup(func_buf);
69 ent->info.file = internal_strdup(file_buf);
70 ent->info.line = line;
71 ent->info.column = col;
72 return ent;
74 static const uptr kMaxAddrFrames = 16;
75 InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
76 for (uptr i = 0; i < kMaxAddrFrames; i++)
77 new(&addr_frames[i]) AddressInfo();
78 uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(
79 addr, addr_frames.data(), kMaxAddrFrames);
80 if (addr_frames_num == 0)
81 return ReportStack::New(addr);
82 ReportStack *top = 0;
83 ReportStack *bottom = 0;
84 for (uptr i = 0; i < addr_frames_num; i++) {
85 ReportStack *cur_entry = ReportStack::New(addr);
86 cur_entry->info = addr_frames[i];
87 if (i == 0)
88 top = cur_entry;
89 else
90 bottom->next = cur_entry;
91 bottom = cur_entry;
93 return top;
96 ReportLocation *SymbolizeData(uptr addr) {
97 DataInfo info;
98 if (!Symbolizer::GetOrInit()->SymbolizeData(addr, &info))
99 return 0;
100 ReportLocation *ent = ReportLocation::New(ReportLocationGlobal);
101 ent->global = info;
102 return ent;
105 void SymbolizeFlush() {
106 Symbolizer::GetOrInit()->Flush();
109 } // namespace __tsan