33 #define _ASTERISK_LOCK_H
39 #define ASTMM_LIBC ASTMM_IGNORE
51 #define ast_free(x) free(x)
52 #define ast_calloc(n, x) calloc(n, x)
53 #define ast_malloc(x) malloc(x)
59 #if defined(HAVE_DLADDR) && defined(HAVE_BFD) && defined(BETTER_BACKTRACES)
62 #ifndef bfd_get_section_size
63 #define bfd_get_section_size(x) bfd_section_size(x)
65 #ifndef bfd_get_section_vma
66 #define bfd_get_section_vma(x, y) bfd_section_vma(y)
68 #ifndef bfd_get_section_flags
69 #define bfd_get_section_flags(x, y) bfd_section_flags(y)
76 #define S_OR(a, b) (a && a[0] != '\0') ? a : b
78 struct ast_bt *__ast_bt_create(
void)
80 struct ast_bt *bt = calloc(1,
sizeof(*bt));
87 ast_bt_get_addresses(bt);
92 int __ast_bt_get_addresses(
struct ast_bt *bt)
98 void *__ast_bt_destroy(
struct ast_bt *bt)
106 #ifdef BETTER_BACKTRACES
120 #define MSG_BUFF_LEN 1024
122 static void process_section(bfd *bfdobj, asection *section,
void *obj)
124 struct bfd_data *data = obj;
125 const char *file, *func;
130 bfd_boolean line_found = 0;
134 offset = data->pc - (data->dynamic ? (bfd_vma)(uintptr_t) data->dli.dli_fbase : 0);
136 if (!(bfd_get_section_flags(bfdobj, section) & SEC_ALLOC)) {
140 vma = bfd_get_section_vma(bfdobj, section);
141 size = bfd_get_section_size(section);
143 if (offset < vma || offset >= vma + size) {
148 line_found = bfd_find_nearest_line(bfdobj, section, data->syms, offset - vma, &file,
161 file = file ? file :
"";
162 fn = strrchr(file,
'/');
163 #define FMT_INLINED "[%s] %s %s:%u %s()"
164 #define FMT_NOT_INLINED "[%p] %s %s:%u %s()"
166 snprintf(data->msg, MSG_BUFF_LEN, inlined ? FMT_INLINED : FMT_NOT_INLINED,
167 inlined ?
"inlined" : (
char *)(uintptr_t) data->pc,
170 line,
S_OR(func,
"???"));
178 }
while (bfd_find_inliner_info(bfdobj, &file, &func, &line));
181 struct ast_vector_string *__ast_bt_get_symbols(
void **addresses,
size_t num_frames)
187 char msg[MSG_BUFF_LEN];
188 static pthread_mutex_t bfd_mutex = PTHREAD_MUTEX_INITIALIZER;
191 if (!return_strings) {
195 free(return_strings);
199 for (stackfr = 0; stackfr < num_frames; stackfr++) {
201 struct bfd_data data = {
202 .return_strings = return_strings,
204 .pc = (bfd_vma)(uintptr_t) addresses[stackfr],
211 if (!dladdr((
void *)(uintptr_t) data.pc, &data.dli)) {
214 data.libname = strrchr(data.dli.dli_fname,
'/');
216 data.libname = data.dli.dli_fname;
221 pthread_mutex_lock(&bfd_mutex);
224 bfdobj = bfd_openr(data.dli.dli_fname, NULL);
230 if (!bfd_check_format(bfdobj, bfd_object)) {
234 data.has_syms = !!(bfd_get_file_flags(bfdobj) & HAS_SYMS);
235 data.dynamic = !!(bfd_get_file_flags(bfdobj) & DYNAMIC);
237 if (!data.has_syms) {
241 allocsize = data.dynamic ?
242 bfd_get_dynamic_symtab_upper_bound(bfdobj) : bfd_get_symtab_upper_bound(bfdobj);
247 data.syms = malloc(allocsize);
252 symbolcount = data.dynamic ?
253 bfd_canonicalize_dynamic_symtab(bfdobj, data.syms) : bfd_canonicalize_symtab(bfdobj, data.syms);
254 if (symbolcount < 0) {
258 bfd_map_over_sections(bfdobj, process_section, &data);
266 pthread_mutex_unlock(&bfd_mutex);
270 snprintf(msg,
sizeof(msg),
"%s %s()",
272 S_OR(data.dli.dli_sname,
"<unknown>"));
277 return return_strings;
281 struct ast_vector_string *__ast_bt_get_symbols(
void **addresses,
size_t num_frames)
288 if (!return_strings) {
292 free(return_strings);
296 strings = backtrace_symbols(addresses, num_frames);
298 for (i = 0; i < num_frames; i++) {
304 return return_strings;
Asterisk main include file. File version handling, generic pbx functions.
Asterisk backtrace generation.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
A structure to hold backtrace information. This structure provides an easy means to store backtrace i...
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Vector container support.
void * addresses[AST_MAX_BT_FRAMES]
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
String vector definitions.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.