From 72694e0dfc4aa8b6b937019c0d093696f5ed2cfb Mon Sep 17 00:00:00 2001 From: Kostyantyn Vorobyov <kostyantyn.vorobyov@cea.fr> Date: Fri, 24 Mar 2017 18:23:09 +0100 Subject: [PATCH] Malloc-free backtrace implementation --- .../e-acsl/share/e-acsl/e_acsl_trace.h | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/plugins/e-acsl/share/e-acsl/e_acsl_trace.h b/src/plugins/e-acsl/share/e-acsl/e_acsl_trace.h index 6e29a4a3427..83fd8679d48 100644 --- a/src/plugins/e-acsl/share/e-acsl/e_acsl_trace.h +++ b/src/plugins/e-acsl/share/e-acsl/e_acsl_trace.h @@ -30,16 +30,47 @@ #include "e_acsl_shexec.h" -# ifdef __GLIBC__ -# include <execinfo.h> -# endif +extern void *__libc_stack_end; + +struct frame_layout { + void *next; + void *return_address; +}; + +/* The following implementation of malloc-free backtrace [native_backtrace] + is mostly taken from Glibc-2.22 (see file debug/backtrace.c) */ +static int native_backtrace (void **array, int size) { + struct frame_layout *current; + void *top_frame, + *top_stack; + int cnt = 0; + + top_frame = __builtin_frame_address(0); + /* Some notion of current stack. Need not be exactly the top of the stack, + just something somewhere in the current frame. */ + top_stack = ({ char __csf; &__csf; }); + + /* We skip the call to this function, it makes no sense to record it. */ + current = ((struct frame_layout *) top_frame); + while (cnt < size) { + /* Assume that the stack grows downwards */ + if ((void *) current < top_stack || !((void *) current < __libc_stack_end)) + /* This means the address is out of range. Note that for the + toplevel we see a frame pointer with value NULL which clearly is + out of range. */ + break; + array[cnt++] = current->return_address; + current = ((struct frame_layout *) (current->next)); + } + return cnt; +} static void trace() { # ifdef __GLIBC__ # ifdef __linux__ int size = 24; void **bb = native_malloc(sizeof(void*)*size); - backtrace(bb,size); + native_backtrace(bb, size); char executable [PATH_MAX]; sprintf(executable, "/proc/%d/exe", getpid()); -- GitLab