2013-02-04 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libsanitizer / tsan / tsan_symbolize.cc
blob015b98717f1f8e025826b4feb8ab2cb38ecde3f1
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 //===----------------------------------------------------------------------===//
12 #include "tsan_symbolize.h"
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"
20 namespace __tsan {
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;
30 // Strip module path to make output shorter.
31 static char *StripModuleName(const char *module) {
32 if (module == 0)
33 return 0;
34 const char *short_module_name = internal_strrchr(module, '/');
35 if (short_module_name)
36 short_module_name += 1;
37 else
38 short_module_name = module;
39 return internal_strdup(short_module_name);
42 static ReportStack *NewReportStackEntry(const AddressInfo &info) {
43 ReportStack *ent = NewReportStackEntry(info.address);
44 ent->module = StripModuleName(info.module);
45 ent->offset = info.module_offset;
46 if (info.function)
47 ent->func = internal_strdup(info.function);
48 if (info.file)
49 ent->file = internal_strdup(info.file);
50 ent->line = info.line;
51 ent->col = info.column;
52 return ent;
55 ReportStack *SymbolizeCode(uptr addr) {
56 if (flags()->external_symbolizer_path[0]) {
57 static const uptr kMaxAddrFrames = 16;
58 InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
59 for (uptr i = 0; i < kMaxAddrFrames; i++)
60 new(&addr_frames[i]) AddressInfo();
61 uptr addr_frames_num = __sanitizer::SymbolizeCode(addr, addr_frames.data(),
62 kMaxAddrFrames);
63 if (addr_frames_num == 0)
64 return NewReportStackEntry(addr);
65 ReportStack *top = 0;
66 ReportStack *bottom = 0;
67 for (uptr i = 0; i < addr_frames_num; i++) {
68 ReportStack *cur_entry = NewReportStackEntry(addr_frames[i]);
69 CHECK(cur_entry);
70 addr_frames[i].Clear();
71 if (i == 0)
72 top = cur_entry;
73 else
74 bottom->next = cur_entry;
75 bottom = cur_entry;
77 return top;
79 return SymbolizeCodeAddr2Line(addr);
82 ReportLocation *SymbolizeData(uptr addr) {
83 if (flags()->external_symbolizer_path[0] == 0)
84 return 0;
85 DataInfo info;
86 if (!__sanitizer::SymbolizeData(addr, &info))
87 return 0;
88 ReportLocation *ent = (ReportLocation*)internal_alloc(MBlockReportStack,
89 sizeof(ReportLocation));
90 internal_memset(ent, 0, sizeof(*ent));
91 ent->type = ReportLocationGlobal;
92 ent->module = StripModuleName(info.module);
93 ent->offset = info.module_offset;
94 if (info.name)
95 ent->name = internal_strdup(info.name);
96 ent->addr = info.start;
97 ent->size = info.size;
98 return ent;
101 } // namespace __tsan