1 //===-- tsan_symbolize.cc -------------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
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"
22 ReportStack
*NewReportStackEntry(uptr addr
) {
23 ReportStack
*ent
= (ReportStack
*)internal_alloc(MBlockReportStack
,
25 internal_memset(ent
, 0, sizeof(*ent
));
30 // Strip module path to make output shorter.
31 static char *StripModuleName(const char *module
) {
34 const char *short_module_name
= internal_strrchr(module
, '/');
35 if (short_module_name
)
36 short_module_name
+= 1;
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
;
47 ent
->func
= internal_strdup(info
.function
);
49 ent
->file
= internal_strdup(info
.file
);
50 ent
->line
= info
.line
;
51 ent
->col
= info
.column
;
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(),
63 if (addr_frames_num
== 0)
64 return NewReportStackEntry(addr
);
66 ReportStack
*bottom
= 0;
67 for (uptr i
= 0; i
< addr_frames_num
; i
++) {
68 ReportStack
*cur_entry
= NewReportStackEntry(addr_frames
[i
]);
70 addr_frames
[i
].Clear();
74 bottom
->next
= cur_entry
;
79 return SymbolizeCodeAddr2Line(addr
);
82 ReportLocation
*SymbolizeData(uptr addr
) {
83 if (flags()->external_symbolizer_path
[0] == 0)
86 if (!__sanitizer::SymbolizeData(addr
, &info
))
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
;
95 ent
->name
= internal_strdup(info
.name
);
96 ent
->addr
= info
.start
;
97 ent
->size
= info
.size
;
101 } // namespace __tsan