Home | History | Annotate | Download | only in rtl
      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