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