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