1 //===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between AddressSanitizer and ThreadSanitizer
11 // run-time libraries.
12 // Libbacktrace implementation of symbolizer parts.
13 //===----------------------------------------------------------------------===//
15 #include "sanitizer_platform.h"
17 #include "sanitizer_internal_defs.h"
18 #include "sanitizer_symbolizer.h"
19 #include "sanitizer_symbolizer_libbacktrace.h"
21 #if SANITIZER_LIBBACKTRACE
22 # include "backtrace-supported.h"
23 # if SANITIZER_POSIX && BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC
24 # include "backtrace.h"
26 # define SANITIZER_LIBBACKTRACE 0
30 namespace __sanitizer
{
32 #if SANITIZER_LIBBACKTRACE
36 struct SymbolizeCodeData
{
40 const char *module_name
;
45 static int SymbolizeCodePCInfoCallback(void *vdata
, uintptr_t addr
,
46 const char *filename
, int lineno
,
47 const char *function
) {
48 SymbolizeCodeData
*cdata
= (SymbolizeCodeData
*)vdata
;
50 AddressInfo
*info
= &cdata
->frames
[cdata
->n_frames
++];
52 info
->FillAddressAndModuleInfo(addr
, cdata
->module_name
,
53 cdata
->module_offset
);
54 info
->function
= internal_strdup(function
);
56 info
->file
= internal_strdup(filename
);
58 if (cdata
->n_frames
== cdata
->max_frames
)
64 static void SymbolizeCodeCallback(void *vdata
, uintptr_t addr
,
65 const char *symname
, uintptr_t, uintptr_t) {
66 SymbolizeCodeData
*cdata
= (SymbolizeCodeData
*)vdata
;
68 AddressInfo
*info
= &cdata
->frames
[0];
70 info
->FillAddressAndModuleInfo(addr
, cdata
->module_name
,
71 cdata
->module_offset
);
72 info
->function
= internal_strdup(symname
);
77 static void SymbolizeDataCallback(void *vdata
, uintptr_t, const char *symname
,
78 uintptr_t symval
, uintptr_t symsize
) {
79 DataInfo
*info
= (DataInfo
*)vdata
;
80 if (symname
&& symval
) {
81 info
->name
= internal_strdup(symname
);
87 static void ErrorCallback(void *, const char *, int) {}
92 LibbacktraceSymbolizer
*LibbacktraceSymbolizer::get(LowLevelAllocator
*alloc
) {
93 // State created in backtrace_create_state is leaked.
94 void *state
= (void *)(backtrace_create_state("/proc/self/exe", 0,
95 ErrorCallback
, NULL
));
98 return new(*alloc
) LibbacktraceSymbolizer(state
);
101 uptr
LibbacktraceSymbolizer::SymbolizeCode(uptr addr
, AddressInfo
*frames
,
103 const char *module_name
,
104 uptr module_offset
) {
105 SymbolizeCodeData data
;
106 data
.frames
= frames
;
108 data
.max_frames
= max_frames
;
109 data
.module_name
= module_name
;
110 data
.module_offset
= module_offset
;
111 backtrace_pcinfo((backtrace_state
*)state_
, addr
, SymbolizeCodePCInfoCallback
,
112 ErrorCallback
, &data
);
114 return data
.n_frames
;
115 backtrace_syminfo((backtrace_state
*)state_
, addr
, SymbolizeCodeCallback
,
116 ErrorCallback
, &data
);
117 return data
.n_frames
;
120 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo
*info
) {
121 backtrace_syminfo((backtrace_state
*)state_
, info
->address
,
122 SymbolizeDataCallback
, ErrorCallback
, info
);
126 #else // SANITIZER_LIBBACKTRACE
128 LibbacktraceSymbolizer
*LibbacktraceSymbolizer::get(LowLevelAllocator
*alloc
) {
132 uptr
LibbacktraceSymbolizer::SymbolizeCode(uptr addr
, AddressInfo
*frames
,
134 const char *module_name
,
135 uptr module_offset
) {
140 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo
*info
) {
144 #endif // SANITIZER_LIBBACKTRACE
146 } // namespace __sanitizer