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 106 #ifdef BETTER_BACKTRACES 109 struct ast_vector_string *return_strings;
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));
183 struct ast_vector_string *return_strings;
187 char msg[MSG_BUFF_LEN];
190 return_strings =
malloc(
sizeof(
struct ast_vector_string));
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;
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);
270 snprintf(msg,
sizeof(msg),
"%s %s()",
272 S_OR(data.dli.dli_sname,
"<unknown>"));
277 return return_strings;
284 struct ast_vector_string *return_strings;
287 return_strings =
malloc(
sizeof(
struct ast_vector_string));
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_MAX_BT_FRAMES
int __ast_bt_get_addresses(struct ast_bt *bt)
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
struct ast_bt * __ast_bt_create(void)
struct ast_vector_string * __ast_bt_get_symbols(void **addresses, size_t num_frames)
void __ast_bt_free_symbols(struct ast_vector_string *symbols)
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define pthread_mutex_lock
Vector container support.
void * addresses[AST_MAX_BT_FRAMES]
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
#define pthread_mutex_unlock
#define ast_bt_get_addresses(bt)
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
void * __ast_bt_destroy(struct ast_bt *bt)