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