]>
Commit | Line | Data |
---|---|---|
cd0be65c WM |
1 | //===-- tsan_symbolize.cc -------------------------------------------------===// |
2 | // | |
3 | // This file is distributed under the University of Illinois Open Source | |
4 | // License. See LICENSE.TXT for details. | |
5 | // | |
6 | //===----------------------------------------------------------------------===// | |
7 | // | |
8 | // This file is a part of ThreadSanitizer (TSan), a race detector. | |
9 | // | |
10 | //===----------------------------------------------------------------------===// | |
11 | ||
12 | #include "tsan_symbolize.h" | |
13 | ||
14 | #include "sanitizer_common/sanitizer_common.h" | |
15 | #include "sanitizer_common/sanitizer_placement_new.h" | |
16 | #include "sanitizer_common/sanitizer_symbolizer.h" | |
17 | #include "tsan_flags.h" | |
18 | #include "tsan_report.h" | |
19 | ||
20 | namespace __tsan { | |
21 | ||
22 | ReportStack *NewReportStackEntry(uptr addr) { | |
23 | ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack, | |
24 | sizeof(ReportStack)); | |
25 | internal_memset(ent, 0, sizeof(*ent)); | |
26 | ent->pc = addr; | |
27 | return ent; | |
28 | } | |
29 | ||
30 | static ReportStack *NewReportStackEntry(const AddressInfo &info) { | |
31 | ReportStack *ent = NewReportStackEntry(info.address); | |
32 | if (info.module) { | |
33 | // Strip module path to make output shorter. | |
34 | const char *short_module_name = internal_strrchr(info.module, '/'); | |
35 | if (short_module_name) | |
36 | short_module_name += 1; | |
37 | else | |
38 | short_module_name = info.module; | |
39 | ent->module = internal_strdup(short_module_name); | |
40 | } | |
41 | ent->offset = info.module_offset; | |
42 | if (info.function) { | |
43 | ent->func = internal_strdup(info.function); | |
44 | } | |
45 | if (info.file) | |
46 | ent->file = internal_strdup(info.file); | |
47 | ent->line = info.line; | |
48 | ent->col = info.column; | |
49 | return ent; | |
50 | } | |
51 | ||
52 | ReportStack *SymbolizeCode(uptr addr) { | |
a0408454 | 53 | if (flags()->external_symbolizer_path[0]) { |
cd0be65c WM |
54 | static const uptr kMaxAddrFrames = 16; |
55 | InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames); | |
56 | for (uptr i = 0; i < kMaxAddrFrames; i++) | |
57 | new(&addr_frames[i]) AddressInfo(); | |
58 | uptr addr_frames_num = __sanitizer::SymbolizeCode(addr, addr_frames.data(), | |
59 | kMaxAddrFrames); | |
60 | if (addr_frames_num == 0) | |
61 | return NewReportStackEntry(addr); | |
62 | ReportStack *top = 0; | |
63 | ReportStack *bottom = 0; | |
64 | for (uptr i = 0; i < addr_frames_num; i++) { | |
65 | ReportStack *cur_entry = NewReportStackEntry(addr_frames[i]); | |
66 | CHECK(cur_entry); | |
67 | addr_frames[i].Clear(); | |
68 | if (i == 0) | |
69 | top = cur_entry; | |
70 | else | |
71 | bottom->next = cur_entry; | |
72 | bottom = cur_entry; | |
73 | } | |
74 | return top; | |
75 | } | |
76 | return SymbolizeCodeAddr2Line(addr); | |
77 | } | |
78 | ||
79 | ReportStack *SymbolizeData(uptr addr) { | |
a0408454 KS |
80 | if (flags()->external_symbolizer_path[0]) { |
81 | AddressInfo frame; | |
82 | if (!__sanitizer::SymbolizeData(addr, &frame)) | |
83 | return 0; | |
84 | return NewReportStackEntry(frame); | |
85 | } | |
cd0be65c WM |
86 | return SymbolizeDataAddr2Line(addr); |
87 | } | |
88 | ||
89 | } // namespace __tsan |