1*7c3d14c8STreehugger Robot //===-- tsan_symbolize.cc -------------------------------------------------===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of ThreadSanitizer (TSan), a race detector.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
13*7c3d14c8STreehugger Robot
14*7c3d14c8STreehugger Robot #include "tsan_symbolize.h"
15*7c3d14c8STreehugger Robot
16*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_common.h"
17*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_placement_new.h"
18*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_symbolizer.h"
19*7c3d14c8STreehugger Robot #include "tsan_flags.h"
20*7c3d14c8STreehugger Robot #include "tsan_report.h"
21*7c3d14c8STreehugger Robot #include "tsan_rtl.h"
22*7c3d14c8STreehugger Robot
23*7c3d14c8STreehugger Robot namespace __tsan {
24*7c3d14c8STreehugger Robot
EnterSymbolizer()25*7c3d14c8STreehugger Robot void EnterSymbolizer() {
26*7c3d14c8STreehugger Robot ThreadState *thr = cur_thread();
27*7c3d14c8STreehugger Robot CHECK(!thr->in_symbolizer);
28*7c3d14c8STreehugger Robot thr->in_symbolizer = true;
29*7c3d14c8STreehugger Robot thr->ignore_interceptors++;
30*7c3d14c8STreehugger Robot }
31*7c3d14c8STreehugger Robot
ExitSymbolizer()32*7c3d14c8STreehugger Robot void ExitSymbolizer() {
33*7c3d14c8STreehugger Robot ThreadState *thr = cur_thread();
34*7c3d14c8STreehugger Robot CHECK(thr->in_symbolizer);
35*7c3d14c8STreehugger Robot thr->in_symbolizer = false;
36*7c3d14c8STreehugger Robot thr->ignore_interceptors--;
37*7c3d14c8STreehugger Robot }
38*7c3d14c8STreehugger Robot
39*7c3d14c8STreehugger Robot // May be overriden by JIT/JAVA/etc,
40*7c3d14c8STreehugger Robot // whatever produces PCs marked with kExternalPCBit.
41*7c3d14c8STreehugger Robot SANITIZER_WEAK_DEFAULT_IMPL
__tsan_symbolize_external(uptr pc,char * func_buf,uptr func_siz,char * file_buf,uptr file_siz,int * line,int * col)42*7c3d14c8STreehugger Robot bool __tsan_symbolize_external(uptr pc, char *func_buf, uptr func_siz,
43*7c3d14c8STreehugger Robot char *file_buf, uptr file_siz, int *line,
44*7c3d14c8STreehugger Robot int *col) {
45*7c3d14c8STreehugger Robot return false;
46*7c3d14c8STreehugger Robot }
47*7c3d14c8STreehugger Robot
SymbolizeCode(uptr addr)48*7c3d14c8STreehugger Robot SymbolizedStack *SymbolizeCode(uptr addr) {
49*7c3d14c8STreehugger Robot // Check if PC comes from non-native land.
50*7c3d14c8STreehugger Robot if (addr & kExternalPCBit) {
51*7c3d14c8STreehugger Robot // Declare static to not consume too much stack space.
52*7c3d14c8STreehugger Robot // We symbolize reports in a single thread, so this is fine.
53*7c3d14c8STreehugger Robot static char func_buf[1024];
54*7c3d14c8STreehugger Robot static char file_buf[1024];
55*7c3d14c8STreehugger Robot int line, col;
56*7c3d14c8STreehugger Robot SymbolizedStack *frame = SymbolizedStack::New(addr);
57*7c3d14c8STreehugger Robot if (__tsan_symbolize_external(addr, func_buf, sizeof(func_buf), file_buf,
58*7c3d14c8STreehugger Robot sizeof(file_buf), &line, &col)) {
59*7c3d14c8STreehugger Robot frame->info.function = internal_strdup(func_buf);
60*7c3d14c8STreehugger Robot frame->info.file = internal_strdup(file_buf);
61*7c3d14c8STreehugger Robot frame->info.line = line;
62*7c3d14c8STreehugger Robot frame->info.column = col;
63*7c3d14c8STreehugger Robot }
64*7c3d14c8STreehugger Robot return frame;
65*7c3d14c8STreehugger Robot }
66*7c3d14c8STreehugger Robot return Symbolizer::GetOrInit()->SymbolizePC(addr);
67*7c3d14c8STreehugger Robot }
68*7c3d14c8STreehugger Robot
SymbolizeData(uptr addr)69*7c3d14c8STreehugger Robot ReportLocation *SymbolizeData(uptr addr) {
70*7c3d14c8STreehugger Robot DataInfo info;
71*7c3d14c8STreehugger Robot if (!Symbolizer::GetOrInit()->SymbolizeData(addr, &info))
72*7c3d14c8STreehugger Robot return 0;
73*7c3d14c8STreehugger Robot ReportLocation *ent = ReportLocation::New(ReportLocationGlobal);
74*7c3d14c8STreehugger Robot internal_memcpy(&ent->global, &info, sizeof(info));
75*7c3d14c8STreehugger Robot return ent;
76*7c3d14c8STreehugger Robot }
77*7c3d14c8STreehugger Robot
SymbolizeFlush()78*7c3d14c8STreehugger Robot void SymbolizeFlush() {
79*7c3d14c8STreehugger Robot Symbolizer::GetOrInit()->Flush();
80*7c3d14c8STreehugger Robot }
81*7c3d14c8STreehugger Robot
82*7c3d14c8STreehugger Robot } // namespace __tsan
83