diff options
author | Kingwel Xie <kingwel.xie@ericsson.com> | 2018-06-15 04:56:24 -0400 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-06-26 15:02:16 +0000 |
commit | 497deaf72f98dd104d9c9999a877ddd2f04c0aa6 (patch) | |
tree | fb86987cf2cebdc4e4cf34d310cebc97541dc708 /src/vppinfra/backtrace.c | |
parent | 6fb0d9b269057a40b6979c741f8c1187b653d12d (diff) |
add backtrace in unix_signal_handler
crash stack backtrace will be directed to syslog
1. make use of glic backtrace in execinfo.h. the old clib_backtrace is removed
2. install SIGABRT in signal handler, but have to remove it when backtrace is
done. reason is to capture stack trace caused by SIGABRT. vPP ASSERT always
call os_exit then abort(). we definitely want to know the trace of this
situation. It is a little tricky to avoid SIGABRT infinite loop
3. always load symbols by calling clib_elf_main_init () in main(). Otherwise,
PC addresses instead of symbols will be displayed.
Change-Id: I150e15b94a4620b2ea4f08c73dc3e6ad1856de1e
Signed-off-by: Kingwel Xie <kingwel.xie@ericsson.com>
Diffstat (limited to 'src/vppinfra/backtrace.c')
-rwxr-xr-x[-rw-r--r--] | src/vppinfra/backtrace.c | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/src/vppinfra/backtrace.c b/src/vppinfra/backtrace.c index bbfb792c656..ca7591c5168 100644..100755 --- a/src/vppinfra/backtrace.c +++ b/src/vppinfra/backtrace.c @@ -219,43 +219,36 @@ backtrace_done: #ifndef clib_backtrace_defined #define clib_backtrace_defined -typedef struct clib_generic_stack_frame_t -{ - struct clib_generic_stack_frame_t *prev; - void *return_address; -} clib_generic_stack_frame_t; +/* use glibc backtrace for stack trace */ +#include <execinfo.h> -/* This will only work if we have a frame pointer. - Without a frame pointer we have to parse the machine code to - parse the stack frames. */ uword clib_backtrace (uword * callers, uword max_callers, uword n_frames_to_skip) { - clib_generic_stack_frame_t *f; - uword i; - - f = __builtin_frame_address (0); - + int size; + void *array[20]; /* Also skip current frame. */ n_frames_to_skip += 1; - for (i = 0; i < max_callers + n_frames_to_skip; i++) + size = clib_min (ARRAY_LEN (array), max_callers + n_frames_to_skip); + + size = backtrace (array, size); + + uword i; + + for (i = 0; i < max_callers + n_frames_to_skip && i < size; i++) { - f = f->prev; - if (!f) - goto backtrace_done; - if (clib_abs ((void *) f - (void *) f->prev) > (64 * 1024)) - goto backtrace_done; if (i >= n_frames_to_skip) - callers[i - n_frames_to_skip] = pointer_to_uword (f->return_address); + callers[i - n_frames_to_skip] = pointer_to_uword (array[i]); } -backtrace_done: if (i < n_frames_to_skip) return 0; else return i - n_frames_to_skip; } + + #endif /* clib_backtrace_defined */ /* |