[Sanitizer] Add rudimentary support for using libbacktrace in symbolizer.
[blocksruntime.git] / lib / sanitizer_common / sanitizer_symbolizer_libbacktrace.cc
blob839aa4cb716f88a2695bff980dc0d130d1ea64d8
1 //===-- sanitizer_symbolizer_libbacktrace.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 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"
25 # else
26 # define SANITIZER_LIBBACKTRACE 0
27 # endif
28 #endif
30 namespace __sanitizer {
32 #if SANITIZER_LIBBACKTRACE
34 namespace {
36 struct SymbolizeCodeData {
37 AddressInfo *frames;
38 uptr n_frames;
39 uptr max_frames;
40 const char *module_name;
41 uptr module_offset;
44 extern "C" {
45 static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,
46 const char *filename, int lineno,
47 const char *function) {
48 SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;
49 if (function) {
50 AddressInfo *info = &cdata->frames[cdata->n_frames++];
51 info->Clear();
52 info->FillAddressAndModuleInfo(addr, cdata->module_name,
53 cdata->module_offset);
54 info->function = internal_strdup(function);
55 if (filename)
56 info->file = internal_strdup(filename);
57 info->line = lineno;
58 if (cdata->n_frames == cdata->max_frames)
59 return 1;
61 return 0;
64 static void SymbolizeCodeCallback(void *vdata, uintptr_t addr,
65 const char *symname, uintptr_t, uintptr_t) {
66 SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;
67 if (symname) {
68 AddressInfo *info = &cdata->frames[0];
69 info->Clear();
70 info->FillAddressAndModuleInfo(addr, cdata->module_name,
71 cdata->module_offset);
72 info->function = internal_strdup(symname);
73 cdata->n_frames = 1;
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);
82 info->start = symval;
83 info->size = symsize;
87 static void ErrorCallback(void *, const char *, int) {}
88 } // extern "C"
90 } // namespace
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));
96 if (!state)
97 return 0;
98 return new(*alloc) LibbacktraceSymbolizer(state);
101 uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,
102 uptr max_frames,
103 const char *module_name,
104 uptr module_offset) {
105 SymbolizeCodeData data;
106 data.frames = frames;
107 data.n_frames = 0;
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);
113 if (data.n_frames)
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);
123 return true;
126 #else // SANITIZER_LIBBACKTRACE
128 LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) {
129 return 0;
132 uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,
133 uptr max_frames,
134 const char *module_name,
135 uptr module_offset) {
136 (void)state_;
137 return 0;
140 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) {
141 return false;
144 #endif // SANITIZER_LIBBACKTRACE
146 } // namespace __sanitizer