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
120#define MSG_BUFF_LEN 1024
122static 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,
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));
187 char msg[MSG_BUFF_LEN];
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;
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.
void * __ast_bt_destroy(struct ast_bt *bt)
void __ast_bt_free_symbols(struct ast_vector_string *symbols)
struct ast_bt * __ast_bt_create(void)
struct ast_vector_string * __ast_bt_get_symbols(void **addresses, size_t num_frames)
int __ast_bt_get_addresses(struct ast_bt *bt)
Asterisk backtrace generation.
#define AST_MAX_BT_FRAMES
#define ast_bt_get_addresses(bt)
#define pthread_mutex_lock
#define pthread_mutex_unlock
A structure to hold backtrace information. This structure provides an easy means to store backtrace i...
void * addresses[AST_MAX_BT_FRAMES]
String vector definitions.
Vector container support.
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.