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 
     22 namespace __tsan {
     23 
     24 ReportStack *NewReportStackEntry(uptr addr) {
     25   ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack,
     26                                                   sizeof(ReportStack));
     27   internal_memset(ent, 0, sizeof(*ent));
     28   ent->pc = addr;
     29   return ent;
     30 }
     31 
     32 static ReportStack *NewReportStackEntry(const AddressInfo &info) {
     33   ReportStack *ent = NewReportStackEntry(info.address);
     34   if (info.module) {
     35     // Strip module path to make output shorter.
     36     const char *short_module_name = internal_strrchr(info.module, '/');
     37     if (short_module_name)
     38       short_module_name += 1;
     39     else
     40       short_module_name = info.module;
     41     ent->module = internal_strdup(short_module_name);
     42   }
     43   ent->offset = info.module_offset;
     44   if (info.function) {
     45     ent->func = internal_strdup(info.function);
     46   }
     47   if (info.file)
     48     ent->file = internal_strdup(info.file);
     49   ent->line = info.line;
     50   ent->col = info.column;
     51   return ent;
     52 }
     53 
     54 ReportStack *SymbolizeCode(uptr addr) {
     55   if (0 != internal_strcmp(flags()->external_symbolizer_path, "")) {
     56     static const uptr kMaxAddrFrames = 16;
     57     InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
     58     for (uptr i = 0; i < kMaxAddrFrames; i++)
     59       new(&addr_frames[i]) AddressInfo();
     60     uptr addr_frames_num = __sanitizer::SymbolizeCode(addr, addr_frames.data(),
     61                                                       kMaxAddrFrames);
     62     if (addr_frames_num == 0)
     63       return NewReportStackEntry(addr);
     64     ReportStack *top = 0;
     65     ReportStack *bottom = 0;
     66     for (uptr i = 0; i < addr_frames_num; i++) {
     67       ReportStack *cur_entry = NewReportStackEntry(addr_frames[i]);
     68       CHECK(cur_entry);
     69       addr_frames[i].Clear();
     70       if (i == 0)
     71         top = cur_entry;
     72       else
     73         bottom->next = cur_entry;
     74       bottom = cur_entry;
     75     }
     76     return top;
     77   }
     78   return SymbolizeCodeAddr2Line(addr);
     79 }
     80 
     81 ReportStack *SymbolizeData(uptr addr) {
     82   return SymbolizeDataAddr2Line(addr);
     83 }
     84 
     85 }  // namespace __tsan
     86