ABRT can now be built against satyr instead of btparser using
--with-satyr parameter to the configure script. RPMs are built against
btparser.

For the most part, the code is changed to use satyr and satyr-compat.h
is provided to wrap btparser in interface mimicking that of satyr. When
the migration to satyr is completed this file can be removed.

Note that the format of core_backtrace problem directory item is
incompatible between these two libraries.

Closes #590. Closes #591. Closes #592. Closes abrt/satyr#47.

Signed-off-by: Martin Milata <mmil...@redhat.com>
---
 configure.ac                                      |  14 +-
 src/daemon/Makefile.am                            |   4 +-
 src/daemon/abrt-handle-event.c                    |  65 ++++-----
 src/include/Makefile.am                           |   3 +-
 src/include/satyr-compat.h                        | 165 ++++++++++++++++++++++
 src/plugins/Makefile.am                           |  12 +-
 src/plugins/abrt-action-analyze-backtrace.c       |  20 ++-
 src/plugins/abrt-action-generate-core-backtrace.c |  23 +++
 src/plugins/ccpp_event.conf                       |   2 +
 9 files changed, 247 insertions(+), 61 deletions(-)
 create mode 100644 src/include/satyr-compat.h

diff --git a/configure.ac b/configure.ac
index b04a5aa..1c93170 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,11 @@ PYTHON_LIBS=`python-config --libs 2> /dev/null`
 AC_SUBST(PYTHON_CFLAGS)
 AC_SUBST(PYTHON_LIBS)
 
+AC_ARG_WITH([satyr],
+    AS_HELP_STRING([--with-satyr],
+        [use satyr instead of btparser (default is no)]),
+    [], [with_satyr=no])
+
 PKG_CHECK_MODULES([GTK], [gtk+-3.0])
 PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.21])
 PKG_CHECK_MODULES([DBUS], [dbus-1])
@@ -82,13 +87,20 @@ PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
 PKG_CHECK_MODULES([RPM], [rpm])
 PKG_CHECK_MODULES([LIBNOTIFY], [libnotify])
 PKG_CHECK_MODULES([NSS], [nss])
-PKG_CHECK_MODULES([BTPARSER], [btparser])
 PKG_CHECK_MODULES([LIBREPORT], [libreport])
 PKG_CHECK_MODULES([LIBREPORT_GTK], [libreport-gtk])
 PKG_CHECK_MODULES([LIBREPORT_WEB], [libreport-web])
 PKG_CHECK_MODULES([POLKIT], [polkit-gobject-1])
 PKG_CHECK_MODULES([GIO], [gio-2.0])
 
+[if test "$with_satyr" = "yes"]
+[then]
+    PKG_CHECK_MODULES([SATYR], [satyr])
+    AC_DEFINE([USE_SATYR], [1], [Use satyr instead of btparser])
+[else]
+    PKG_CHECK_MODULES([SATYR], [btparser])
+[fi]
+
 PKG_PROG_PKG_CONFIG
 AC_ARG_WITH([systemdsystemunitdir],
         AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for 
systemd service files]),
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index c3892d4..9578569 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -50,12 +50,12 @@ abrt_handle_event_CPPFLAGS = \
     -I$(srcdir)/../lib \
     $(GLIB_CFLAGS) \
     $(LIBREPORT_CFLAGS) \
-    $(BTPARSER_CFLAGS) \
+    $(SATYR_CFLAGS) \
     -D_GNU_SOURCE
 abrt_handle_event_LDADD = \
     ../lib/libabrt.la \
     $(LIBREPORT_LIBS) \
-    $(BTPARSER_LIBS)
+    $(SATYR_LIBS)
 
 abrt_action_save_package_data_SOURCES = \
     rpm.h rpm.c \
diff --git a/src/daemon/abrt-handle-event.c b/src/daemon/abrt-handle-event.c
index 29fbffd..e11d192 100644
--- a/src/daemon/abrt-handle-event.c
+++ b/src/daemon/abrt-handle-event.c
@@ -19,55 +19,39 @@
 
 #include "libabrt.h"
 #include <libreport/run_event.h>
-
-#include <btparser/frame.h>
-#include <btparser/thread.h>
-#include <btparser/normalize.h>
-#include <btparser/metrics.h>
-#include <btparser/core-backtrace.h>
-
-#define BACKTRACE_DUP_THRESHOLD 2
+#include "satyr-compat.h"
 
 static char *uid = NULL;
 static char *uuid = NULL;
-static struct btp_thread *corebt = NULL;
+static struct sr_core_stacktrace *corebt = NULL;
 static char *crash_dump_dup_name = NULL;
 
-
-#if 0
-/* Useful only for debugging. */
-static void print_thread(const struct btp_thread *thread)
-{
-    struct btp_frame *frame;
-
-    for (frame = thread->frames; frame != NULL; frame = frame->next)
-    {
-        struct frame_aux *aux = frame->user_data;
-        printf("%s %s+0x%jx %s %s\n", frame->function_name, aux->build_id,
-                (uintmax_t)frame->address, aux->modname, aux->fingerprint);
-    }
-}
-#endif
-
-
-static int core_backtrace_is_duplicate(struct btp_thread *bt1, const char 
*bt2_text)
+static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1,
+                                       const char *bt2_text)
 {
     int result;
-    struct btp_thread *bt2 = btp_load_core_backtrace(bt2_text);
+    char *error_message;
+    struct sr_core_stacktrace *bt2 = 
sr_core_stacktrace_from_json_text(bt2_text, &error_message);
     if (bt2 == NULL)
     {
-        VERB1 log("Failed to parse backtrace, considering it not duplicate");
+        VERB1 log("Failed to parse backtrace, considering it not duplicate: 
%s", error_message);
+        free(error_message);
         return 0;
     }
-    else if (btp_thread_get_frame_count(bt2) <= 0)
+
+    struct sr_core_thread *thread1 = sr_core_stacktrace_find_crash_thread(bt1);
+    struct sr_core_thread *thread2 = sr_core_stacktrace_find_crash_thread(bt2);
+
+    if (sr_core_thread_get_frame_count(thread2) <= 0)
     {
         VERB1 log("Core backtrace has zero frames, considering it not 
duplicate");
         result = 0;
         goto end;
     }
 
-    int distance = btp_thread_levenshtein_distance_custom(bt1, bt2, true,
-                                                          
btp_core_backtrace_frame_cmp);
+    int distance = sr_distance_core(SR_DISTANCE_DAMERAU_LEVENSHTEIN,
+                                    thread1, thread2);
+
     if (distance == -1)
     {
         result = 0;
@@ -79,7 +63,7 @@ static int core_backtrace_is_duplicate(struct btp_thread 
*bt1, const char *bt2_t
     }
 
 end:
-    btp_free_core_backtrace(bt2);
+    sr_core_stacktrace_free(bt2);
 
     return result;
 }
@@ -107,7 +91,7 @@ static int dup_uuid_compare(const struct dump_dir *dd)
      * XXX: this relies on the fact that backtrace is created in the same event
      * as UUID
      */
-    if (corebt && btp_thread_get_frame_count(corebt) > 0)
+    if (corebt)
         return 0;
 
     dd_uuid = dd_load_text_ext(dd, FILENAME_UUID, DD_FAIL_QUIETLY_ENOENT);
@@ -140,13 +124,14 @@ static void dup_corebt_init(const struct dump_dir *dd)
     if (!corebt_text)
         return; /* no backtrace */
 
-    corebt = btp_load_core_backtrace(corebt_text);
+    char *error_message;
+    corebt = sr_core_stacktrace_from_json_text(corebt_text,
+                                                &error_message);
 
-    if (corebt && btp_thread_get_frame_count(corebt) <= 0)
+    if (!corebt)
     {
-        VERB1 log("Core backtrace of the crash has zero frames");
-        btp_free_core_backtrace(corebt);
-        corebt = NULL;
+        VERB1 log("Failed to load core stacktrace: %s", error_message);
+        free(error_message);
     }
 
     free(corebt_text);
@@ -175,7 +160,7 @@ static int dup_corebt_compare(const struct dump_dir *dd)
 
 static void dup_corebt_fini(void)
 {
-    btp_free_core_backtrace(corebt);
+    sr_core_stacktrace_free(corebt);
     corebt = NULL;
 }
 
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index a4f24b9..ed63afd 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -4,4 +4,5 @@ libabrt_includedir = \
 libabrt_include_HEADERS = \
     libabrt.h \
     abrt-dbus.h \
-    hooklib.h
+    hooklib.h \
+    satyr-compat.h
diff --git a/src/include/satyr-compat.h b/src/include/satyr-compat.h
new file mode 100644
index 0000000..0752785
--- /dev/null
+++ b/src/include/satyr-compat.h
@@ -0,0 +1,165 @@
+/*
+    Copyright (C) 2013 RedHat inc.
+
+    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 2 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, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+/*
+ * Compatibility header for transition from btparser to satyr. When the
+ * possibility to compile abrt against btparser is removed, delete this file
+ * and include the relevant satyr headers instead.
+ */
+#ifndef SATYR_COMPAT_H_
+#define SATYR_COMPAT_H_
+
+#include "config.h"
+
+#ifdef USE_SATYR
+/* Satyr is used, nothing to do, just include everything we may need. */
+
+#include <satyr/core_frame.h>
+#include <satyr/core_stacktrace.h>
+#include <satyr/core_thread.h>
+#include <satyr/distance.h>
+#include <satyr/gdb_frame.h>
+#include <satyr/gdb_stacktrace.h>
+#include <satyr/location.h>
+#include <satyr/metrics.h>
+#include <satyr/normalize.h>
+#include <satyr/sha1.h>
+#include <satyr/utils.h>
+
+#define BACKTRACE_DUP_THRESHOLD 0.3
+
+#else /* USE_SATYR */
+/* We use btparser. Wrap the calls to btparser in a satyr-compatible 
interface. */
+
+#include <btparser/frame.h>
+#include <btparser/thread.h>
+#include <btparser/normalize.h>
+#include <btparser/metrics.h>
+#include <btparser/core-backtrace.h>
+#include <btparser/backtrace.h>
+#include <btparser/frame.h>
+#include <btparser/location.h>
+#include "libabrt.h" /* xstrdup */
+
+#define BACKTRACE_DUP_THRESHOLD 2
+
+/* abrt-handle-event.c */
+#define sr_core_stacktrace btp_thread
+#define sr_core_thread btp_thread
+#define sr_thread_get_frame_count btp_thread_get_frame_count
+
+enum sr_distance_type
+{
+    SR_DISTANCE_DAMERAU_LEVENSHTEIN
+};
+
+/* The functions should be static but that generates unused function warnings.
+ * We don't include this header in two compilation units that are then linked
+ * together anyway, so this should work. And this file should be gone soon ...
+ */
+struct sr_core_stacktrace *
+sr_core_stacktrace_from_json_text(const char *text,
+                                  char **error_message)
+{
+    struct btp_thread *thread = btp_load_core_backtrace(text);
+    if (!thread)
+    {
+        *error_message = xstrdup(
+            "Failed to parse backtrace, considering it not duplicate");
+        return NULL;
+    }
+    return btp_load_core_backtrace(text);
+}
+
+struct sr_core_thread *
+sr_core_stacktrace_find_crash_thread(struct sr_core_stacktrace *stacktrace)
+{
+    return stacktrace;
+}
+
+int
+sr_core_thread_get_frame_count(struct sr_core_thread *thread)
+{
+    return btp_thread_get_frame_count(thread);
+}
+
+float
+sr_distance_core(enum sr_distance_type distance_type,
+                 struct sr_core_thread *thread1,
+                 struct sr_core_thread *thread2)
+{
+    return btp_thread_levenshtein_distance_custom(thread1, thread2, true,
+        btp_core_backtrace_frame_cmp);
+}
+
+void
+sr_core_stacktrace_free(struct sr_core_stacktrace *stacktrace)
+{
+    btp_free_core_backtrace(stacktrace);
+}
+
+/* abrt-action-analyze-backtrace.c */
+#define sr_location btp_location
+#define sr_gdb_stacktrace btp_backtrace
+#define sr_gdb_frame btp_frame
+
+void
+sr_location_init(struct sr_location *location)
+{
+    btp_location_init(location);
+}
+
+struct sr_gdb_stacktrace *
+sr_gdb_stacktrace_parse(const char **input,
+                        struct sr_location *location)
+{
+    return btp_backtrace_parse(input, location);
+}
+
+char *
+sr_gdb_stacktrace_get_duplication_hash(struct sr_gdb_stacktrace *stacktrace)
+{
+    return btp_backtrace_get_duplication_hash(stacktrace);
+}
+
+float
+sr_gdb_stacktrace_quality_complex(struct sr_gdb_stacktrace *stacktrace)
+{
+    return btp_backtrace_quality_complex(stacktrace);
+}
+
+struct sr_gdb_frame *
+sr_gdb_stacktrace_get_crash_frame(struct sr_gdb_stacktrace *stacktrace)
+{
+    return btp_backtrace_get_crash_frame(stacktrace);
+}
+
+void
+sr_gdb_frame_free(struct sr_gdb_frame *frame)
+{
+    btp_frame_free(frame);
+}
+
+void
+sr_gdb_stacktrace_free(struct sr_gdb_stacktrace *stacktrace)
+{
+    btp_backtrace_free(stacktrace);
+}
+
+#endif /* USE_SATYR */
+
+#endif /* SATYR_COMPAT_H_ */
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 6ace57f..b249bf1 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -212,11 +212,11 @@ abrt_action_generate_core_backtrace_CPPFLAGS = \
     -DLOCALSTATEDIR='"$(localstatedir)"' \
     $(GLIB_CFLAGS) \
     $(LIBREPORT_CFLAGS) \
-    $(BTPARSER_CFLAGS) \
+    $(SATYR_CFLAGS) \
     -D_GNU_SOURCE
 abrt_action_generate_core_backtrace_LDADD = \
     $(LIBREPORT_LIBS) \
-    $(BTPARSER_LIBS) \
+    $(SATYR_LIBS) \
     ../lib/libabrt.la
 
 abrt_action_analyze_backtrace_SOURCES = \
@@ -226,11 +226,11 @@ abrt_action_analyze_backtrace_CPPFLAGS = \
     -I$(srcdir)/../lib \
     $(GLIB_CFLAGS) \
     $(LIBREPORT_CFLAGS) \
-    $(BTPARSER_CFLAGS) \
+    $(SATYR_CFLAGS) \
     -D_GNU_SOURCE
 abrt_action_analyze_backtrace_LDADD = \
     $(LIBREPORT_LIBS) \
-    $(BTPARSER_LIBS)
+    $(SATYR_LIBS)
 
 abrt_action_install_debuginfo_to_abrt_cache_SOURCES = \
     abrt-action-install-debuginfo-to-abrt-cache.c
@@ -258,7 +258,7 @@ abrt_retrace_client_SOURCES = \
      $(LIBREPORT_CFLAGS)
  abrt_retrace_client_LDADD = \
      $(LIBREPORT_LIBS) \
-     $(BTPARSER_LIBS) \
+     $(SATYR_LIBS) \
      $(NSS_LIBS)
 
 abrt_dedup_client_SOURCES = \
@@ -273,7 +273,7 @@ abrt_dedup_client_SOURCES = \
      $(LIBREPORT_CFLAGS)
  abrt_dedup_client_LDADD = \
      $(LIBREPORT_LIBS) \
-     $(BTPARSER_LIBS) \
+     $(SATYR_LIBS) \
      $(NSS_LIBS)
 
 abrt_bodhi_SOURCES = \
diff --git a/src/plugins/abrt-action-analyze-backtrace.c 
b/src/plugins/abrt-action-analyze-backtrace.c
index 1ef1488..a980213 100644
--- a/src/plugins/abrt-action-analyze-backtrace.c
+++ b/src/plugins/abrt-action-analyze-backtrace.c
@@ -15,9 +15,7 @@
     with this program; if not, write to the Free Software Foundation, Inc.,
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
-#include <btparser/backtrace.h>
-#include <btparser/frame.h>
-#include <btparser/location.h>
+#include "satyr-compat.h"
 #include "libabrt.h"
 
 static const char *dump_dir_name = ".";
@@ -83,10 +81,10 @@ int main(int argc, char **argv)
     }
 
     /* Compute backtrace hash */
-    struct btp_location location;
-    btp_location_init(&location);
+    struct sr_location location;
+    sr_location_init(&location);
     const char *backtrace_str_ptr = backtrace_str;
-    struct btp_backtrace *backtrace = btp_backtrace_parse(&backtrace_str_ptr, 
&location);
+    struct sr_gdb_stacktrace *backtrace = 
sr_gdb_stacktrace_parse(&backtrace_str_ptr, &location);
     free(backtrace_str);
 
     /* Store backtrace hash */
@@ -132,7 +130,7 @@ int main(int argc, char **argv)
     }
 
     /* Compute duplication hash. */
-    char *str_hash_core = btp_backtrace_get_duplication_hash(backtrace);
+    char *str_hash_core = sr_gdb_stacktrace_get_duplication_hash(backtrace);
     struct strbuf *str_hash = strbuf_new();
     strbuf_append_str(str_hash, component);
     strbuf_append_str(str_hash, str_hash_core);
@@ -146,7 +144,7 @@ int main(int argc, char **argv)
     free(str_hash_core);
 
     /* Compute the backtrace rating. */
-    float quality = btp_backtrace_quality_complex(backtrace);
+    float quality = sr_gdb_stacktrace_quality_complex(backtrace);
     const char *rating;
     if (quality < 0.6f)
         rating = "0";
@@ -161,7 +159,7 @@ int main(int argc, char **argv)
     dd_save_text(dd, FILENAME_RATING, rating);
 
     /* Get the function name from the crash frame. */
-    struct btp_frame *crash_frame = btp_backtrace_get_crash_frame(backtrace);
+    struct sr_gdb_frame *crash_frame = 
sr_gdb_stacktrace_get_crash_frame(backtrace);
     if (crash_frame)
     {
         if (crash_frame->function_name &&
@@ -169,9 +167,9 @@ int main(int argc, char **argv)
         {
             dd_save_text(dd, FILENAME_CRASH_FUNCTION, 
crash_frame->function_name);
         }
-        btp_frame_free(crash_frame);
+        sr_gdb_frame_free(crash_frame);
     }
-    btp_backtrace_free(backtrace);
+    sr_gdb_stacktrace_free(backtrace);
     dd_close(dd);
     free(component);
     return 0;
diff --git a/src/plugins/abrt-action-generate-core-backtrace.c 
b/src/plugins/abrt-action-generate-core-backtrace.c
index ef24e1e..303afc3 100644
--- a/src/plugins/abrt-action-generate-core-backtrace.c
+++ b/src/plugins/abrt-action-generate-core-backtrace.c
@@ -17,6 +17,27 @@
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 #include "libabrt.h"
+
+#ifdef USE_SATYR
+/* If satyr is used, just run "satyr abrt-create-core-stacktrace" on the dump 
directory.
+ */
+
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+    VERB1 log("Running 'satyr abrt-create-core-stacktrace .'");
+    execlp("satyr", "satyr", "abrt-create-core-stacktrace", ".", NULL);
+    perror_msg_and_die("Can't execute satyr");
+
+    return 0;
+}
+
+#else /* USE_SATYR */
+/* Btparser is used. Once the support is removed, this whole file can be
+ * deleted and ccpp_event.conf modified accordingly.
+ */
+
 #include <btparser/hash_sha1.h>
 #include <btparser/utils.h>
 #include <btparser/core-backtrace.h>
@@ -198,3 +219,5 @@ int main(int argc, char **argv)
     btp_core_backtrace_free(backtrace);
     return 0;
 }
+
+#endif /* USE_SATYR */
diff --git a/src/plugins/ccpp_event.conf b/src/plugins/ccpp_event.conf
index b608c2d..dfc4908 100644
--- a/src/plugins/ccpp_event.conf
+++ b/src/plugins/ccpp_event.conf
@@ -16,6 +16,8 @@ EVENT=post-create analyzer=CCpp
         fi
         # Try generating backtrace, if it fails we can still use
         # the UUID generated by abrt-action-analyze-c
+        ##satyr migration:
+        #satyr abrt-create-core-stacktrace "$DUMP_DIR"
         abrt-action-generate-core-backtrace
         abrt-action-analyze-c &&
         abrt-action-list-dsos -m maps -o dso_list &&
-- 
1.7.11.7

Reply via email to