[gimp/gimp-2-10] app: add source location information to the Linux GimpBacktrace backend
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: add source location information to the Linux GimpBacktrace backend
- Date: Sun, 23 Sep 2018 02:41:44 +0000 (UTC)
commit b065ff7de7fc382c7c78c2c1ae9cfa57c30b01ba
Author: Ell <ell_se yahoo com>
Date: Sat Sep 22 22:33:44 2018 -0400
app: add source location information to the Linux GimpBacktrace backend
When libbacktrace is available, use it to retrieve source location
information in the Linux GimpBacktrace backend.
(cherry picked from commit 7cdd1ebeefcbc9e7f48fa4bdeee7ce9c2a7cb436)
app/Makefile.am | 1 +
app/core/gimpbacktrace-linux.c | 159 +++++++++++++++++++++++++++--------------
app/tests/Makefile.am | 1 +
configure.ac | 43 ++++++++++-
4 files changed, 149 insertions(+), 55 deletions(-)
---
diff --git a/app/Makefile.am b/app/Makefile.am
index 3f14db4286..86aec105f2 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -180,6 +180,7 @@ gimpconsoleldadd = \
$(Z_LIBS) \
$(JSON_C_LIBS) \
$(LIBMYPAINT_LIBS) \
+ $(LIBBACKTRACE_LIBS) \
$(LIBUNWIND_LIBS) \
$(INTLLIBS) \
$(RT_LIBS) \
diff --git a/app/core/gimpbacktrace-linux.c b/app/core/gimpbacktrace-linux.c
index 477aa0a096..cef207a43a 100644
--- a/app/core/gimpbacktrace-linux.c
+++ b/app/core/gimpbacktrace-linux.c
@@ -44,6 +44,10 @@
#include <string.h>
#include <stdio.h>
+#ifdef HAVE_LIBBACKTRACE
+#include <backtrace.h>
+#endif
+
#ifdef HAVE_LIBUNWIND
#define UNW_LOCAL_ONLY
#include <libunwind.h>
@@ -110,6 +114,10 @@ static pid_t blacklisted_threads[MAX_N_THREADS];
static gint n_blacklisted_threads;
static GimpBacktrace *handler_backtrace;
+#ifdef HAVE_LIBBACKTRACE
+static struct backtrace_state *backtrace_state;
+#endif
+
static const gchar *blacklisted_thread_names[] =
{
"gmain"
@@ -271,6 +279,9 @@ gimp_backtrace_signal_handler (gint signum)
void
gimp_backtrace_init (void)
{
+#ifdef HAVE_LIBBACKTRACE
+ backtrace_state = backtrace_create_state (NULL, 0, NULL, NULL);
+#endif
}
gboolean
@@ -565,75 +576,115 @@ gimp_backtrace_get_frame_address (GimpBacktrace *backtrace,
return backtrace->threads[thread].frames[frame];
}
+#ifdef HAVE_LIBBACKTRACE
+static void
+gimp_backtrace_syminfo_callback (GimpBacktraceAddressInfo *info,
+ guintptr pc,
+ const gchar *symname,
+ guintptr symval,
+ guintptr symsize)
+{
+ if (symname)
+ g_strlcpy (info->symbol_name, symname, sizeof (info->symbol_name));
+
+ info->symbol_address = symval;
+}
+
+static gint
+gimp_backtrace_pcinfo_callback (GimpBacktraceAddressInfo *info,
+ guintptr pc,
+ const gchar *filename,
+ gint lineno,
+ const gchar *function)
+{
+ if (function)
+ g_strlcpy (info->symbol_name, function, sizeof (info->symbol_name));
+
+ if (filename)
+ g_strlcpy (info->source_file, filename, sizeof (info->source_file));
+
+ info->source_line = lineno;
+
+ return 0;
+}
+#endif /* HAVE_LIBBACKTRACE */
+
gboolean
gimp_backtrace_get_address_info (guintptr address,
GimpBacktraceAddressInfo *info)
{
- Dl_info dl_info;
+ Dl_info dl_info;
+ gboolean result = FALSE;
g_return_val_if_fail (info != NULL, FALSE);
-#ifdef HAVE_LIBUNWIND
- {
- unw_context_t context = {};
- unw_cursor_t cursor;
- unw_word_t offset;
-
- if (dladdr ((gpointer) address, &dl_info) && dl_info.dli_fname)
- {
- g_strlcpy (info->object_name, dl_info.dli_fname,
- sizeof (info->object_name));
- }
- else
- {
- info->object_name[0] = '\0';
- }
-
- if (unw_init_local (&cursor, &context) == 0 &&
- unw_set_reg (&cursor, UNW_REG_IP, address) == 0 &&
- unw_get_proc_name (&cursor,
- info->symbol_name, sizeof (info->symbol_name),
- &offset) == 0)
- {
- info->symbol_address = address - offset;
- }
- else
- {
- info->symbol_name[0] = '\0';
- info->symbol_address = 0;
- }
- }
-#else
- if (! dladdr ((gpointer) address, &dl_info))
- return FALSE;
-
- if (dl_info.dli_fname)
- {
- g_strlcpy (info->object_name, dl_info.dli_fname,
- sizeof (info->object_name));
- }
- else
- {
- info->object_name[0] = '\0';
- }
+ info->object_name[0] = '\0';
+
+ info->symbol_name[0] = '\0';
+ info->symbol_address = 0;
+
+ info->source_file[0] = '\0';
+ info->source_line = 0;
- if (dl_info.dli_sname)
+ if (dladdr ((gpointer) address, &dl_info))
{
- g_strlcpy (info->symbol_name, dl_info.dli_sname,
- sizeof (info->symbol_name));
+ if (dl_info.dli_fname)
+ {
+ g_strlcpy (info->object_name, dl_info.dli_fname,
+ sizeof (info->object_name));
+ }
+
+ if (dl_info.dli_sname)
+ {
+ g_strlcpy (info->symbol_name, dl_info.dli_sname,
+ sizeof (info->symbol_name));
+ }
+
+ info->symbol_address = (guintptr) dl_info.dli_saddr;
+
+ result = TRUE;
}
- else
+
+#ifdef HAVE_LIBBACKTRACE
+ if (backtrace_state)
{
- info->symbol_name[0] = '\0';
+ backtrace_syminfo (
+ backtrace_state, address,
+ (backtrace_syminfo_callback) gimp_backtrace_syminfo_callback,
+ NULL,
+ info);
+
+ backtrace_pcinfo (
+ backtrace_state, address,
+ (backtrace_full_callback) gimp_backtrace_pcinfo_callback,
+ NULL,
+ info);
+
+ result = TRUE;
}
+#endif /* HAVE_LIBBACKTRACE */
- info->symbol_address = (guintptr) dl_info.dli_saddr;
-#endif
+#ifdef HAVE_LIBUNWIND
+ if (! info->symbol_name[0])
+ {
+ unw_context_t context = {};
+ unw_cursor_t cursor;
+ unw_word_t offset;
+
+ if (unw_init_local (&cursor, &context) == 0 &&
+ unw_set_reg (&cursor, UNW_REG_IP, address) == 0 &&
+ unw_get_proc_name (&cursor,
+ info->symbol_name, sizeof (info->symbol_name),
+ &offset) == 0)
+ {
+ info->symbol_address = address - offset;
- info->source_file[0] = '\0';
- info->source_line = 0;
+ result = TRUE;
+ }
+ }
+#endif /* HAVE_LIBUNWIND */
- return TRUE;
+ return result;
}
diff --git a/app/tests/Makefile.am b/app/tests/Makefile.am
index 766c2b732c..e7191b4483 100644
--- a/app/tests/Makefile.am
+++ b/app/tests/Makefile.am
@@ -136,6 +136,7 @@ LDADD = \
$(Z_LIBS) \
$(JSON_C_LIBS) \
$(LIBMYPAINT_LIBS) \
+ $(LIBBACKTRACE_LIBS) \
$(LIBUNWIND_LIBS) \
$(INTLLIBS) \
$(RT_LIBS) \
diff --git a/configure.ac b/configure.ac
index 29f48c7631..3f07f5136a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1831,6 +1831,43 @@ AC_SUBST(FILE_HEIF)
AM_CONDITIONAL(HAVE_LIBHEIF, test "x$have_libheif" = xyes)
+########################
+# Check for libbacktrace
+########################
+
+AC_ARG_WITH(libbacktrace, [ --without-libbacktrace build without libbacktrace support])
+
+have_libbacktrace=no
+if test "x$with_libbacktrace" != xno; then
+ gimp_save_LIBS=$LIBS
+ LIBS="$LIBS -lbacktrace"
+
+ AC_MSG_CHECKING([for LIBBACKTRACE])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stddef.h>
+ #include <backtrace.h>
+ #include <backtrace-supported.h>
+
+ #if ! BACKTRACE_SUPPORTED
+ #error ! BACKTRACE_SUPPORTED
+ #endif
+ ]],
+ [[(void) backtrace_create_state (NULL, 0, NULL, NULL);]])],
+ [AC_MSG_RESULT([yes]); LIBBACKTRACE_LIBS='-lbacktrace'],
+ [AC_MSG_RESULT([no]); have_libbacktrace='no (libbacktrace is not found or not supported)'])
+
+ LIBS=$gimp_save_LIBS
+
+ AC_SUBST(LIBBACKTRACE_LIBS)
+fi
+
+if test "x$have_libbacktrace" = xyes; then
+ AC_DEFINE(HAVE_LIBBACKTRACE, 1,
+ [Define to 1 if libbacktrace is available])
+fi
+
+
#####################
# Check for libunwind
#####################
@@ -1857,7 +1894,11 @@ fi
detailed_backtraces=no
if test "x$platform_linux" = xyes; then
- detailed_backtraces=$have_libunwind
+ if test "x$have_libbacktrace" = xyes -o "x$have_libunwind" = xyes; then
+ detailed_backtraces=yes
+ else
+ detailed_backtraces='no (libbacktrace and libunwind are not found or not supported)'
+ fi
elif test "x$platform_win32" = xyes; then
detailed_backtraces=$enable_drmingw
fi
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]