[sysprof/wip/chergert/mem-preload: 14/43] preload: use backtrace() as fallback for libunwind



commit a037c77ce1515854833c3922301f222d78024813
Author: Christian Hergert <chergert redhat com>
Date:   Sun Feb 2 16:50:35 2020 -0800

    preload: use backtrace() as fallback for libunwind

 meson.build                                       | 10 ++---
 src/libsysprof/preload/meson.build                |  6 ++-
 src/libsysprof/preload/sysprof-memory-collector.c | 51 ++++++++++++++++-------
 3 files changed, 45 insertions(+), 22 deletions(-)
---
diff --git a/meson.build b/meson.build
index 2d97c0a..cde3d5b 100644
--- a/meson.build
+++ b/meson.build
@@ -179,17 +179,17 @@ int main(void) {
   error('Sysprof requires a C compiler with stdatomic support such as GCC 4.9 or newer')
 endif
 
-configure_file(
-         output: 'config.h',
-  configuration: config_h
-)
-
 subdir('src')
 subdir('data')
 subdir('examples')
 subdir('help')
 subdir('po')
 
+configure_file(
+         output: 'config.h',
+  configuration: config_h
+)
+
 if get_option('enable_gtk')
   meson.add_install_script('build-aux/meson/post_install.sh')
 endif
diff --git a/src/libsysprof/preload/meson.build b/src/libsysprof/preload/meson.build
index 2d298ac..b32d838 100644
--- a/src/libsysprof/preload/meson.build
+++ b/src/libsysprof/preload/meson.build
@@ -1,9 +1,13 @@
+libunwind_dep = dependency('libunwind-generic', required: false)
+
 libsysprof_memory_preload_deps = [
   libsysprof_capture_dep,
   cc.find_library('dl', required: false),
-  dependency('libunwind-generic'),
+  libunwind_dep,
 ]
 
+config_h.set10('ENABLE_LIBUNWIND', libunwind_dep.found())
+
 libsysprof_memory_preload = shared_library('sysprof-memory-collector',
   ['sysprof-memory-collector.c'],
   dependencies: libsysprof_memory_preload_deps,
diff --git a/src/libsysprof/preload/sysprof-memory-collector.c 
b/src/libsysprof/preload/sysprof-memory-collector.c
index a0ae98f..66a05a2 100644
--- a/src/libsysprof/preload/sysprof-memory-collector.c
+++ b/src/libsysprof/preload/sysprof-memory-collector.c
@@ -1,6 +1,9 @@
 #define _GNU_SOURCE
 
+#include "config.h"
+
 #include <dlfcn.h>
+#include <execinfo.h>
 #include <sched.h>
 #include <stdlib.h>
 #include <sys/syscall.h>
@@ -144,27 +147,43 @@ track_malloc (void   *ptr,
               size_t  size)
 {
   SysprofCaptureAddress addrs[CAPTURE_MAX_STACK_DEPTH];
-  unw_context_t uc;
-  unw_cursor_t cursor;
-  unw_word_t ip;
+#if !ENABLE_LIBUNWIND && GLIB_SIZEOF_VOID_P != 8
+  gpointer voidp_addrs[CAPTURE_MAX_STACK_DEPTH];
+#endif
   guint n_addrs = 0;
 
   if G_UNLIKELY (!writer)
     return;
 
-  /* Get a stacktrace for the current allocation, but walk past our
-   * current function because we don't care about that stack frame.
-   */
-  unw_getcontext (&uc);
-  unw_init_local (&cursor, &uc);
-  if (unw_step (&cursor) > 0)
-    {
-      while (n_addrs < G_N_ELEMENTS (addrs) && unw_step (&cursor) > 0)
-        {
-          unw_get_reg (&cursor, UNW_REG_IP, &ip);
-          addrs[n_addrs++] = ip;
-        }
-    }
+#if ENABLE_LIBUNWIND
+  {
+    unw_context_t uc;
+    unw_cursor_t cursor;
+    unw_word_t ip;
+
+    /* Get a stacktrace for the current allocation, but walk past our
+     * current function because we don't care about that stack frame.
+     */
+    unw_getcontext (&uc);
+    unw_init_local (&cursor, &uc);
+    if (unw_step (&cursor) > 0)
+      {
+        while (n_addrs < G_N_ELEMENTS (addrs) && unw_step (&cursor) > 0)
+          {
+            unw_get_reg (&cursor, UNW_REG_IP, &ip);
+            addrs[n_addrs++] = ip;
+          }
+      }
+  }
+#else
+#if GLIB_SIZEOF_VOID_P == 8
+  n_addrs = backtrace ((void **)addrs, CAPTURE_MAX_STACK_DEPTH);
+# else
+  n_addrs = backtrace (voidp_addrs, CAPTURE_MAX_STACK_DEPTH);
+  for (guint i = 0; i < n_addrs; i++)
+    addrs[i] = GPOINTER_TO_SIZE (voidp_addrs[i]);
+# endif
+#endif
 
   G_LOCK (writer);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]