diff options
author | William Pitcock <nenolod@dereferenced.org> | 2017-06-14 13:09:23 -0500 |
---|---|---|
committer | William Pitcock <nenolod@dereferenced.org> | 2017-06-14 13:09:23 -0500 |
commit | f67416822a54109bd9cfa0fd210d7d8f53412ced (patch) | |
tree | 7d3d14933f39ca160d706d1bec25ce541a188962 /libgcompat/backtrace.c | |
parent | 2b58008b911d9dc8354b9001e22b594fa6456dd1 (diff) | |
download | gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.tar.gz gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.tar.bz2 gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.tar.xz gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.zip |
move all compatibility library stuff into libgcompat/
Diffstat (limited to 'libgcompat/backtrace.c')
-rw-r--r-- | libgcompat/backtrace.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/libgcompat/backtrace.c b/libgcompat/backtrace.c new file mode 100644 index 0000000..2ceb334 --- /dev/null +++ b/libgcompat/backtrace.c @@ -0,0 +1,44 @@ +#include <dlfcn.h> +#include <stddef.h> +#include <stdlib.h> + +#define _frame_level(addr_buf, curr, frame, size) \ + if(__builtin_frame_address(frame) != NULL && (curr = __builtin_return_address(frame)) > 0x1000 && frame <= size) addr_buf[frame] = curr; \ + else return size; + +int backtrace(void **addr_buf, int size) +{ + void *curr; + _frame_level(addr_buf, curr, 0, size) + _frame_level(addr_buf, curr, 1, size) + _frame_level(addr_buf, curr, 2, size) + _frame_level(addr_buf, curr, 3, size) + _frame_level(addr_buf, curr, 4, size) + _frame_level(addr_buf, curr, 5, size) + _frame_level(addr_buf, curr, 6, size) + _frame_level(addr_buf, curr, 7, size) + _frame_level(addr_buf, curr, 8, size) + _frame_level(addr_buf, curr, 9, size) + return 9; +} + +char **backtrace_symbols(void * const *addr_buf, int size) +{ + char **result = calloc(sizeof(char *), size); + if(result == NULL) return result; + + for(int next = 0; next < size; next++) + { + Dl_info info; + int err = dladdr(addr_buf[next], &info); + + if(err != 0) + { + result[next] = "??:0"; + } else { + result[next] = info.dli_sname; + } + } + + return result; +} |