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