• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
NewReportStackEntry(uptr addr)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 
NewReportStackEntry(const AddressInfo & info)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 
SymbolizeCode(uptr addr)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 
SymbolizeData(uptr addr)81 ReportStack *SymbolizeData(uptr addr) {
82   return SymbolizeDataAddr2Line(addr);
83 }
84 
85 }  // namespace __tsan
86