[gimp] app: add source location information to the Linux GimpBacktrace backend
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add source location information to the Linux GimpBacktrace backend
- Date: Sun, 23 Sep 2018 02:41:49 +0000 (UTC)
commit 7cdd1ebeefcbc9e7f48fa4bdeee7ce9c2a7cb436
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.
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 114a809caf..fda2e5fafb 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -181,6 +181,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 55dd04c2c7..3b6076f7c4 100644
--- a/app/tests/Makefile.am
+++ b/app/tests/Makefile.am
@@ -138,6 +138,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 ed6cd74652..6cff17fa28 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1791,6 +1791,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
#####################
@@ -1817,7 +1854,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]