[sysprof] preload: move backtrace helper into helper



commit f7a53ca8f9e7a6b5cbe84ca136f5dbf0b49c45f4
Author: Christian Hergert <chergert redhat com>
Date:   Thu Mar 12 19:51:36 2020 -0700

    preload: move backtrace helper into helper
    
    This is useful so that we can have more of these LD_PRELOAD tools without
    having to duplicate this code.

 src/libsysprof/preload/backtrace-helper.h         | 83 +++++++++++++++++++++++
 src/libsysprof/preload/sysprof-memory-collector.c | 78 +++++++--------------
 2 files changed, 106 insertions(+), 55 deletions(-)
---
diff --git a/src/libsysprof/preload/backtrace-helper.h b/src/libsysprof/preload/backtrace-helper.h
new file mode 100644
index 0000000..1915a42
--- /dev/null
+++ b/src/libsysprof/preload/backtrace-helper.h
@@ -0,0 +1,83 @@
+/* backtrace-helper.h
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#ifdef HAVE_EXECINFO_H
+# include <execinfo.h>
+#endif
+#ifdef ENABLE_LIBUNWIND
+# define UNW_LOCAL_ONLY
+# include <libunwind.h>
+#endif
+
+static void
+backtrace_init (void)
+{
+#ifdef ENABLE_LIBUNWIND
+  unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
+# ifdef HAVE_UNW_SET_CACHE_SIZE
+  unw_set_cache_size (unw_local_addr_space, 1024, 0);
+#endif
+#endif
+}
+
+static gint
+backtrace_func (SysprofCaptureAddress *addrs,
+                guint                  n_addrs,
+                gpointer               user_data)
+{
+#if defined(ENABLE_LIBUNWIND)
+# if GLIB_SIZEOF_VOID_P == 8
+  /* We know that collector will overwrite fields *AFTER* it
+   * has called the backtrace function allowing us to cheat
+   * and subtract an offset from addrs to avoid having to
+   * copy frame pointers around.
+   */
+  return unw_backtrace ((void **)addrs - 2, n_addrs) - 2;
+# else
+  static const gint skip = 2;
+  void **stack = alloca (n_addrs * sizeof (gpointer));
+  gint n = unw_backtrace (stack, n_addrs);
+  for (guint i = skip; i < n; i++)
+    addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]);
+  return MAX (0, n - skip);
+# endif
+#elif defined(HAVE_EXECINFO_H)
+# if GLIB_SIZEOF_VOID_P == 8
+  /* See note on unw_backtrace() */
+  return backtrace ((void **)addrs - 2, n_addrs) - 2;
+# else /* GLIB_SIZEOF_VOID_P != 8 */
+  static const gint skip = 2;
+  void **stack = alloca (n_addrs * sizeof (gpointer));
+  gint n = backtrace (stack, n_addrs);
+  for (guint i = skip; i < n; i++)
+    addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]);
+  return MAX (0, n - skip);
+# endif /* GLIB_SIZEOF_VOID_P */
+#else
+  return 0;
+#endif
+}
+
diff --git a/src/libsysprof/preload/sysprof-memory-collector.c 
b/src/libsysprof/preload/sysprof-memory-collector.c
index 002370f..30591c8 100644
--- a/src/libsysprof/preload/sysprof-memory-collector.c
+++ b/src/libsysprof/preload/sysprof-memory-collector.c
@@ -1,15 +1,28 @@
+/* sysprof-memory-collector.c
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
 #define _GNU_SOURCE
 
 #include "config.h"
 
 #include <dlfcn.h>
-#ifdef HAVE_EXECINFO_H
-# include <execinfo.h>
-#endif
-#ifdef ENABLE_LIBUNWIND
-# define UNW_LOCAL_ONLY
-# include <libunwind.h>
-#endif
 #include <sched.h>
 #include <stdlib.h>
 #include <sys/syscall.h>
@@ -17,6 +30,8 @@
 #include <sysprof-capture.h>
 #include <unistd.h>
 
+#include "backtrace-helper.h"
+
 #include "gconstructor.h"
 
 typedef void *(* RealMalloc)        (size_t);
@@ -62,58 +77,11 @@ G_DEFINE_CONSTRUCTOR(collector_init_ctor)
 static void
 collector_init_ctor (void)
 {
-#ifdef ENABLE_LIBUNWIND
-  unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
-# ifdef HAVE_UNW_SET_CACHE_SIZE
-  unw_set_cache_size (unw_local_addr_space, 1024, 0);
-#endif
-#endif
+  backtrace_init ();
   sysprof_collector_init ();
   collector_ready = TRUE;
 }
 
-static gint
-backtrace_func (SysprofCaptureAddress *addrs,
-                guint                  n_addrs,
-                gpointer               user_data)
-{
-  /* Ensure we have at least two pointers to steal temporarily below */
-  G_STATIC_ASSERT (G_STRUCT_OFFSET (SysprofCaptureSample, addrs) >= 16);
-  G_STATIC_ASSERT (G_STRUCT_OFFSET (SysprofCaptureAllocation, addrs) >= 16);
-
-#if defined(ENABLE_LIBUNWIND)
-# if GLIB_SIZEOF_VOID_P == 8
-  /* We know that collector will overwrite fields *AFTER* it
-   * has called the backtrace function allowing us to cheat
-   * and subtract an offset from addrs to avoid having to
-   * copy frame pointers around.
-   */
-  return unw_backtrace ((void **)addrs - 2, n_addrs) - 2;
-# else
-  static const gint skip = 2;
-  void **stack = alloca (n_addrs * sizeof (gpointer));
-  gint n = unw_backtrace (stack, n_addrs);
-  for (guint i = skip; i < n; i++)
-    addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]);
-  return MAX (0, n - skip);
-# endif
-#elif defined(HAVE_EXECINFO_H)
-# if GLIB_SIZEOF_VOID_P == 8
-  /* See note on unw_backtrace() */
-  return backtrace ((void **)addrs - 2, n_addrs) - 2;
-# else /* GLIB_SIZEOF_VOID_P != 8 */
-  static const gint skip = 2;
-  void **stack = alloca (n_addrs * sizeof (gpointer));
-  gint n = backtrace (stack, n_addrs);
-  for (guint i = skip; i < n; i++)
-    addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]);
-  return MAX (0, n - skip);
-# endif /* GLIB_SIZEOF_VOID_P */
-#else
-  return 0;
-#endif
-}
-
 static void *
 scratch_malloc (size_t size)
 {


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