Related to abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com --- configure.ac | 18 +-- libreport-web.pc.in | 2 +- src/lib/json.c | 288 +--------------------------------------- src/plugins/reporter-bugzilla.c | 67 +++------- 4 files changed, 20 insertions(+), 355 deletions(-)
diff --git a/configure.ac b/configure.ac index 671d6a4..da7f480 100644 --- a/configure.ac +++ b/configure.ac @@ -145,11 +145,6 @@ 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([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) @@ -158,18 +153,7 @@ PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([PROXY], [libproxy-1.0], [ AC_DEFINE([HAVE_PROXY], [1], [Use libproxy]) ], [:]) - -[if test "$with_satyr" = "yes"] -[then] - PKG_CHECK_MODULES([SATYR], [satyr]) - AC_DEFINE([USE_SATYR], [1], [Use satyr instead of btparser]) - SATYR_PKG="satyr" -[else] - PKG_CHECK_MODULES([SATYR], [btparser]) - SATYR_PKG="btparser" -[fi] -AC_SUBST(SATYR_PKG) -AM_CONDITIONAL([USE_SATYR], [test "$with_satyr" = "yes"]) +PKG_CHECK_MODULES([SATYR], [satyr])
AC_ARG_WITH(newt, AS_HELP_STRING([--with-newt],[use newt (default is YES)]), diff --git a/libreport-web.pc.in b/libreport-web.pc.in index ec4ab8e..288e613 100644 --- a/libreport-web.pc.in +++ b/libreport-web.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libreport Description: Library providing network API for libreport Version: @VERSION@ -Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json @SATYR_PKG@ libreport +Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json satyr libreport Libs: -L${libdir} -lreport-web Cflags:
diff --git a/src/lib/json.c b/src/lib/json.c index d5c6f2d..68348ad 100644 --- a/src/lib/json.c +++ b/src/lib/json.c @@ -19,6 +19,9 @@
#include <json/json.h>
+#include <satyr/abrt.h> +#include <satyr/report.h> + #include "internal_libreport.h" #include "ureport.h" #include "libreport_curl.h" @@ -34,11 +37,6 @@ static void ureport_add_str(struct json_object *ur, const char *key, json_object_object_add(ur, key, jstring); }
-#if USE_SATYR - -#include <satyr/abrt.h> -#include <satyr/report.h> - char *ureport_from_dump_dir(const char *dump_dir_path) { char *error_message; @@ -54,286 +52,6 @@ char *ureport_from_dump_dir(const char *dump_dir_path) return json_ureport; }
-#else /* USE_SATYR */ - -#include <btparser/thread.h> -#include <btparser/core-backtrace.h> - -/* on success 1 returned, on error zero is returned and appropriate value - * is returned as third argument. You should never read third argument when - * function fails - * - * json-c library doesn't have any json_object_new_long, - * thus we have to use only int - */ -static int get_pd_int_item(problem_data_t *pd, const char *key, int *result) -{ - if (!pd || !key) - return 0; - - char *pd_item = problem_data_get_content_or_NULL(pd, key); - if (!pd_item) - { - VERB1 log("warning: '%s' is not an item in problem directory", key); - return 0; - } - - errno = 0; - char *e; - long i = strtol(pd_item, &e, 10); - if (errno || pd_item == e || *e != '\0' || (int) i != i) - return 0; - - *result = i; - return 1; -} - -static void ureport_add_int(struct json_object *ur, const char *key, int i) -{ - struct json_object *jint = json_object_new_int(i); - if (!jint) - die_out_of_memory(); - - json_object_object_add(ur, key, jint); -} - -static void ureport_add_os(struct json_object *ur, problem_data_t *pd) -{ - char *name; - char *version; - map_string_t *osinfo = new_map_string(); - problem_data_get_osinfo(pd, osinfo); - parse_osinfo_for_rhts(osinfo, &name, &version); - free_map_string(osinfo); - - if (!name || !version) - { - free(name); - free(version); - return; - } - - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_str(jobject, "name", name); - ureport_add_str(jobject, "version", version); - - free(name); - free(version); - - json_object_object_add(ur, "os", jobject); -} - -static bool ureport_add_type(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); - if (!pd_item) - { - error_msg(_("Missing problem element '%s'"), FILENAME_ANALYZER); - return false; - } - - if (strcmp(pd_item, "CCpp") == 0) - ureport_add_str(ur, "type", "USERSPACE"); - else if (strcmp(pd_item, "Python") == 0) - ureport_add_str(ur, "type", "PYTHON"); - else if (strcmp(pd_item, "Kerneloops") == 0 || strcmp(pd_item, "vmcore") == 0) - ureport_add_str(ur, "type", "KERNELOOPS"); - else - { - error_msg(_("An unsupported value '%s' in problem element '%s'"), pd_item, FILENAME_ANALYZER); - return false; - } - - return true; -} - -static void ureport_add_core_backtrace(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_CORE_BACKTRACE); - if (!pd_item) - return; - - struct btp_thread *core_bt = btp_load_core_backtrace(pd_item); - if (!core_bt) - return; - - struct json_object *jarray = json_object_new_array(); - if (!jarray) - die_out_of_memory(); - - struct btp_frame *frame; - unsigned frame_nr = 0; - for (frame = core_bt->frames; frame; frame = frame->next) - { - struct frame_aux *aux = frame->user_data; - - struct json_object *item = json_object_new_object(); - if (!item) - die_out_of_memory(); - - if (aux->filename) - ureport_add_str(item, "path", aux->filename); - - if (frame->function_name) - ureport_add_str(item, "funcname", frame->function_name); - - if (aux->build_id) - ureport_add_str(item, "buildid", aux->build_id); - - if (aux->fingerprint) - ureport_add_str(item, "funchash", aux->fingerprint); - - /* always add offset - even offset 0 is valid */ - ureport_add_int(item, "offset", (uintmax_t)frame->address); - - ureport_add_int(item, "frame", frame_nr++); - ureport_add_int(item, "thread", 0); - - - json_object_array_add(jarray, item); - } - - btp_thread_free(core_bt); - - json_object_object_add(ur, FILENAME_CORE_BACKTRACE, jarray); -} -static void ureport_add_item_str(struct json_object *ur, problem_data_t *pd, - const char *key, const char *rename) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, key); - if (!pd_item) - return; - - ureport_add_str(ur, (rename) ?: key, pd_item); -} - -static void ureport_add_item_int(struct json_object *ur, problem_data_t *pd, - const char *key, const char *rename) -{ - int nr; - int stat = get_pd_int_item(pd, key, &nr); - if (!stat) - return; - - ureport_add_int(ur, (rename) ?: key, nr); -} - -static void ureport_add_pkg(struct json_object *ur, problem_data_t *pd) -{ - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_item_int(jobject, pd, FILENAME_PKG_EPOCH, "epoch"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_NAME, "name"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_VERSION, "version"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_RELEASE, "release"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_ARCH, "architecture"); - - json_object_object_add(ur, "installed_package", jobject); -} - -static void ureport_add_related_pkgs(struct json_object *ur, problem_data_t *pd) -{ - // TODO: populate this field - struct json_object *jobject = json_object_new_array(); - json_object_object_add(ur, "related_packages", jobject); -} - -static void ureport_add_reporter(struct json_object *ur, const char *name, const char *version) -{ - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_str(jobject, "name", name); - ureport_add_str(jobject, "version", version); - - json_object_object_add(ur, "reporter", jobject); -} - -static void ureport_add_oops(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); - if (!pd_item) - return; - - if (!strcmp(pd_item, "Kerneloops")) - ureport_add_item_str(ur, pd, FILENAME_BACKTRACE, "oops"); -} - -char *new_json_ureport(problem_data_t *pd) -{ - struct json_object *ureport = json_object_new_object(); - if (!ureport) - die_out_of_memory(); - - ureport_add_item_str(ureport, pd, "user_type", NULL); - ureport_add_item_int(ureport, pd, "uptime", NULL); - - /* mandatory, but not in problem-dir - * - * ureport_add_item_int(ureport, pd, "crash_thread", NULL); - */ - ureport_add_int(ureport, "ureport_version", 1); - ureport_add_int(ureport, "crash_thread", 0); - - ureport_add_item_str(ureport, pd, FILENAME_ARCHITECTURE, NULL); - ureport_add_item_str(ureport, pd, FILENAME_EXECUTABLE, NULL); - ureport_add_item_str(ureport, pd, FILENAME_REASON, NULL); - ureport_add_item_str(ureport, pd, FILENAME_COMPONENT, NULL); - - if (!ureport_add_type(ureport, pd)) - { - error_msg(_("Can't create an uReport without 'type'")); - json_object_put(ureport); - return NULL; - } - - ureport_add_pkg(ureport, pd); - ureport_add_related_pkgs(ureport, pd); - ureport_add_os(ureport, pd); - - ureport_add_core_backtrace(ureport, pd); - ureport_add_reporter(ureport, "ABRT", VERSION); - - ureport_add_oops(ureport, pd); - - char *j = xstrdup(json_object_to_json_string(ureport)); - json_object_put(ureport); - - return j; -} - -char *ureport_from_dump_dir(const char *dump_dir_path) -{ - struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY); - if (!dd) - xfunc_die(); - - problem_data_t *pd = create_problem_data_from_dump_dir(dd); - - dd_close(dd); - if (!pd) - xfunc_die(); /* create_problem_data_from_dump_dir already emitted error msg */ - - char *json_ureport = new_json_ureport(pd); - problem_data_free(pd); - - if (json_ureport == NULL) - { - error_msg(_("Not uploading an empty uReport")); - return NULL; - } - - return json_ureport; -} - -#endif /* USE_SATYR */ - char *new_json_attachment(const char *bthash, const char *type, const char *data) { struct json_object *attachment = json_object_new_object(); diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c index 626b41f..ef453c1 100644 --- a/src/plugins/reporter-bugzilla.c +++ b/src/plugins/reporter-bugzilla.c @@ -21,39 +21,8 @@ #include "abrt_xmlrpc.h" #include "rhbz.h"
-/* btparser compatibility - once we move to satyr, the else branch of the ifdef - * can be removed - */ -#ifdef USE_SATYR - -#include <satyr/location.h> -#include <satyr/gdb_stacktrace.h> -#include <satyr/gdb_thread.h> -#include <satyr/gdb_frame.h> -#include <satyr/strbuf.h> - -#else /* USE_SATYR */ - -#include <btparser/location.h> -#include <btparser/backtrace.h> -#include <btparser/thread.h> -#include <btparser/frame.h> -#include <btparser/strbuf.h> - -#define sr_location btp_location -#define sr_location_init btp_location_init -#define sr_gdb_stacktrace btp_backtrace -#define sr_gdb_stacktrace_parse btp_backtrace_parse -#define sr_gdb_stacktrace_get_optimized_thread btp_backtrace_get_optimized_thread -#define sr_gdb_stacktrace_free btp_backtrace_free -#define sr_gdb_thread btp_thread -#define sr_gdb_thread_append_to_str btp_thread_append_to_str -#define sr_gdb_thread_free btp_thread_free -#define sr_strbuf btp_strbuf -#define sr_strbuf_new btp_strbuf_new -#define sr_strbuf_free_nobuf btp_strbuf_free_nobuf - -#endif /* USE_SATYR */ +#include <satyr/stacktrace.h> +#include <satyr/abrt.h>
struct section_t { char *name; @@ -365,38 +334,32 @@ int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data,
if (strlen(item->content) >= max_text_size) { - struct sr_location location; - sr_location_init(&location); + char *error_msg = NULL; + const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER); + if (!analyzer) + return 0;
- /* sr_gdb_stacktrace_parse modifies the input parameter */ + /* sr_stacktrace_parse modifies the input parameter */ char *content = item->content; - struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location); + struct sr_stacktrace *backtrace = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer), + (const char **)&content, &error_msg);
if (!backtrace) { - log(_("Can't parse backtrace")); + log(_("Can't parse backtrace: %s"), error_msg); + free(error_msg); return 0; }
/* Get optimized thread stack trace for 10 top most frames */ - struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10); - - sr_gdb_stacktrace_free(backtrace); + truncated = sr_stacktrace_to_short_text(backtrace, 10); + sr_stacktrace_free(backtrace);
- if (!thread) + if (!truncated) { - log(_("Can't find crash thread")); + log(_("Can't generate stacktrace description (no crash thread?)")); return 0; } - - /* Cannot be NULL, it dies on memory error */ - struct sr_strbuf *bt = sr_strbuf_new(); - - sr_gdb_thread_append_to_str(thread, bt, true); - - sr_gdb_thread_free(thread); - - truncated = sr_strbuf_free_nobuf(bt); }
append_text(result,
Signed-off-by: Martin Milata mmilata@redhat.com --- libreport.spec.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libreport.spec.in b/libreport.spec.in index ba3465b..f6a6a76 100644 --- a/libreport.spec.in +++ b/libreport.spec.in @@ -40,12 +40,10 @@ BuildRequires: asciidoc BuildRequires: xmlto BuildRequires: newt-devel BuildRequires: libproxy-devel -BuildRequires: btparser-devel +BuildRequires: satyr-devel %if %{with bugzilla} BuildRequires: xmlrpc-c-devel %endif -##satyr migration: -#BuildRequires: satyr-devel BuildRequires: doxygen Requires: libreport-filesystem = %{version}-%{release} # required for update from old report library, otherwise we obsolete report-gtk
On Mon, 2013-07-08 at 17:47 +0200, Martin Milata wrote:
Signed-off-by: Martin Milata mmilata@redhat.com
libreport.spec.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libreport.spec.in b/libreport.spec.in index ba3465b..f6a6a76 100644 --- a/libreport.spec.in +++ b/libreport.spec.in @@ -40,12 +40,10 @@ BuildRequires: asciidoc BuildRequires: xmlto BuildRequires: newt-devel BuildRequires: libproxy-devel -BuildRequires: btparser-devel +BuildRequires: satyr-devel
Shouldn't we restrict satyr version somehow? Perhaps like we require libreport package in abrt spec file?
I propose these changes: Requires: satyr >= 0.4 BuildRequires: satyr-devel >= 0.4
If you agree, I will commit the proposed changed.
%if %{with bugzilla} BuildRequires: xmlrpc-c-devel %endif -##satyr migration: -#BuildRequires: satyr-devel BuildRequires: doxygen Requires: libreport-filesystem = %{version}-%{release} # required for update from old report library, otherwise we obsolete report-gtk
On Mon, 2013-07-08 at 19:19 +0200, Jakub Filak wrote:
On Mon, 2013-07-08 at 17:47 +0200, Martin Milata wrote:
Signed-off-by: Martin Milata mmilata@redhat.com
libreport.spec.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libreport.spec.in b/libreport.spec.in index ba3465b..f6a6a76 100644 --- a/libreport.spec.in +++ b/libreport.spec.in @@ -40,12 +40,10 @@ BuildRequires: asciidoc BuildRequires: xmlto BuildRequires: newt-devel BuildRequires: libproxy-devel -BuildRequires: btparser-devel +BuildRequires: satyr-devel
Shouldn't we restrict satyr version somehow? Perhaps like we require libreport package in abrt spec file?
I propose these changes: Requires: satyr >= 0.4 BuildRequires: satyr-devel >= 0.4
If you agree, I will commit the proposed changed.
OK, 'Requires: satyr >= 0.4' is not necessary because rpmbuild automatically adds a dependency on libsatyr.so.1()(64bit) to all packages which needs it. But satyr's soversion is out of date and doesn't reflect changes in ABI between 0.3 version and 0.4 version. So, I'll add the require line and we can remove it once satyr starts correct soversioning.
%if %{with bugzilla} BuildRequires: xmlrpc-c-devel %endif -##satyr migration: -#BuildRequires: satyr-devel BuildRequires: doxygen Requires: libreport-filesystem = %{version}-%{release} # required for update from old report library, otherwise we obsolete report-gtk
Closes abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com --- configure.ac | 14 +- doc/abrt-action-generate-core-backtrace.txt | 50 +----- src/daemon/abrt-handle-event.c | 81 +++++----- src/include/Makefile.am | 1 - src/include/satyr-compat.h | 171 -------------------- src/plugins/abrt-action-analyze-backtrace.c | 41 +++-- src/plugins/abrt-action-generate-core-backtrace.c | 180 ++-------------------- src/plugins/koops_event.conf | 1 - src/plugins/python_event.conf | 1 - src/plugins/vmcore_event.conf | 1 - 10 files changed, 92 insertions(+), 449 deletions(-) delete mode 100644 src/include/satyr-compat.h
diff --git a/configure.ac b/configure.ac index ccd3901..7b32618 100644 --- a/configure.ac +++ b/configure.ac @@ -92,11 +92,6 @@ 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]) @@ -109,14 +104,7 @@ 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_CHECK_MODULES([SATYR], [satyr])
PKG_PROG_PKG_CONFIG AC_ARG_WITH([systemdsystemunitdir], diff --git a/doc/abrt-action-generate-core-backtrace.txt b/doc/abrt-action-generate-core-backtrace.txt index 0e68031..988327f 100644 --- a/doc/abrt-action-generate-core-backtrace.txt +++ b/doc/abrt-action-generate-core-backtrace.txt @@ -3,12 +3,11 @@ abrt-action-generate-core-backtrace(1)
NAME ---- -abrt-action-generate-core-backtrace - Generates coredump-level (debuginfo-free) -backtrace +abrt-action-generate-core-backtrace - Generates coredump-level backtrace
SYNOPSIS -------- -'abrt-action-generate-core-backtrace' [-v] [-d DIR] +'abrt-action-generate-core-backtrace' [-v] [-r] [-d DIR]
DESCRIPTION ----------- @@ -22,8 +21,7 @@ However, it only contains information that can be obtained from the coredump without debugging symbols available - mainly relative addresses of the stored instruction pointers. Such backtrace can still be useful for reporting and reproducing the bug and does not require debugging -information files to be installed. See <<X1,*FILE FORMAT*>> for the -description of the generated file. +information files to be installed.
The result is saved in the problem directory in a file named 'core_backtrace'. @@ -45,48 +43,12 @@ OPTIONS -d DIR:: Path to problem directory.
+-r:: + Do not hash function fingerprints. Useful for debugging. + -v:: Be more verbose. Can be given multiple times.
-[[X1]] -FILE FORMAT ------------ - -The generated file is a text file containing one line for each stack frame of -the thread that most likely caused the crash. The line has following format: - ------------- -BUILD_ID OFFSET SYMBOL MODNAME FINGERPRINT ------------- - -Where: - -*BUILD_ID*:: - Build ID of the binary file the address is mapped to as a hexadecimal string. - -*OFFSET*:: - Offset from the start of the executable section of aforementioned file the - stored instruction pointer points to. Number in hexadecimal format. - -*SYMBOL*:: - Name of the function if it is present in the binary (which is often the case - for shared libraries). - -*MODNAME*:: - Name of the module. Contains name of a library or *[exe]* if it is the - executable. - -*FINGERPRINT*:: - Fingerprint of the function the instruction pointer points to (x86-64 only). - The fingerprint is generated from various aspects of the machine code of the - function in question. Its purpose is to supplant the BUILD_ID and OFFSET - pair in case they are not present and to allow for comparison of - coredump-level backtraces produced by two slightly different versions of a - program. - -Dash in place of any of the parts indicates that the part is unknown. - -
AUTHORS ------- diff --git a/src/daemon/abrt-handle-event.c b/src/daemon/abrt-handle-event.c index a426566..eadb058 100644 --- a/src/daemon/abrt-handle-event.c +++ b/src/daemon/abrt-handle-event.c @@ -16,22 +16,42 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <satyr/thread.h> +#include <satyr/stacktrace.h> +#include <satyr/distance.h> +#include <satyr/abrt.h>
#include "libabrt.h" #include <libreport/run_event.h> -#include "satyr-compat.h" + +/* 70 % similarity */ +#define BACKTRACE_DUP_THRESHOLD 0.3
static char *uid = NULL; static char *uuid = NULL; -static struct sr_core_stacktrace *corebt = NULL; +static struct sr_stacktrace *corebt = NULL; +static char *analyzer = NULL; static char *crash_dump_dup_name = NULL;
-static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, +static char* load_backtrace(const struct dump_dir *dd) +{ + const char *filename = FILENAME_BACKTRACE; + if (strcmp(analyzer, "CCpp") == 0) + { + filename = FILENAME_CORE_BACKTRACE; + } + + return dd_load_text_ext(dd, filename, + DD_FAIL_QUIETLY_ENOENT|DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); +} + +static int core_backtrace_is_duplicate(struct sr_stacktrace *bt1, const char *bt2_text) { int result; char *error_message; - struct sr_core_stacktrace *bt2 = sr_core_stacktrace_from_json_text(bt2_text, &error_message); + struct sr_stacktrace *bt2 = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer), + bt2_text, &error_message); if (bt2 == NULL) { VERB1 log("Failed to parse backtrace, considering it not duplicate: %s", error_message); @@ -39,10 +59,10 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, return 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); + struct sr_thread *thread1 = sr_stacktrace_find_crash_thread(bt1); + struct sr_thread *thread2 = sr_stacktrace_find_crash_thread(bt2);
- int length2 = sr_core_thread_get_frame_count(thread2); + int length2 = sr_thread_frame_count(thread2);
if (length2 <= 0) { @@ -52,7 +72,7 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, }
/* This is an ugly workaround for https://github.com/abrt/btparser/issues/6 */ -#ifndef USE_SATYR + /* int length1 = sr_core_thread_get_frame_count(thread1);
if (length1 <= 2 || length2 <= 2) @@ -61,23 +81,14 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, result = (sr_core_thread_cmp(thread1, thread2) == 0); goto end; } -#endif - - float distance = sr_distance_core(SR_DISTANCE_DAMERAU_LEVENSHTEIN, - thread1, thread2); + */
- if (distance == -1) - { - result = 0; - } - else - { - VERB2 log("Distance between backtraces: %f", distance); - result = (distance <= BACKTRACE_DUP_THRESHOLD); - } + float distance = sr_distance(SR_DISTANCE_DAMERAU_LEVENSHTEIN, thread1, thread2); + VERB2 log("Distance between backtraces: %f", distance); + result = (distance <= BACKTRACE_DUP_THRESHOLD);
end: - sr_core_stacktrace_free(bt2); + sr_stacktrace_free(bt2);
return result; } @@ -126,22 +137,17 @@ static void dup_uuid_fini(void)
static void dup_corebt_init(const struct dump_dir *dd) { - char *corebt_text; - if (corebt) return; /* already checked */
- corebt_text = dd_load_text_ext(dd, FILENAME_CORE_BACKTRACE, - DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE - ); - + char *corebt_text = load_backtrace(dd); if (!corebt_text) return; /* no backtrace */
+ /* sr_stacktrace_parse moves the pointer */ char *error_message; - corebt = sr_core_stacktrace_from_json_text(corebt_text, - &error_message); - + corebt = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer), + corebt_text, &error_message); if (!corebt) { VERB1 log("Failed to load core stacktrace: %s", error_message); @@ -157,9 +163,8 @@ static int dup_corebt_compare(const struct dump_dir *dd) return 0;
int isdup; - char *dd_corebt = dd_load_text_ext(dd, FILENAME_CORE_BACKTRACE, - DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
+ char *dd_corebt = load_backtrace(dd); if (!dd_corebt) return 0;
@@ -174,7 +179,7 @@ static int dup_corebt_compare(const struct dump_dir *dd)
static void dup_corebt_fini(void) { - sr_core_stacktrace_free(corebt); + sr_stacktrace_free(corebt); corebt = NULL; }
@@ -208,13 +213,13 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param) if (!dd) return 0; /* wtf? (error, but will be handled elsewhere later) */
- dup_uuid_init(dd); - dup_corebt_init(dd); - - char *analyzer = dd_load_text(dd, FILENAME_ANALYZER); + analyzer = dd_load_text(dd, FILENAME_ANALYZER); /* dump_dir_name can be relative */ dump_dir_name = realpath(dump_dir_name, NULL);
+ dup_uuid_init(dd); + dup_corebt_init(dd); + dd_close(dd);
DIR *dir = opendir(g_settings_dump_location); diff --git a/src/include/Makefile.am b/src/include/Makefile.am index addbaa5..49a6f5c 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -5,5 +5,4 @@ libabrt_include_HEADERS = \ libabrt.h \ abrt-dbus.h \ hooklib.h \ - satyr-compat.h \ problem_api.h diff --git a/src/include/satyr-compat.h b/src/include/satyr-compat.h deleted file mode 100644 index 23f6bb7..0000000 --- a/src/include/satyr-compat.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - 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.0 - -/* abrt-handle-event.c */ -#define sr_core_stacktrace btp_thread -#define sr_core_thread btp_thread - -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); -} - -int -sr_core_thread_cmp(struct sr_core_thread *thread1, - struct sr_core_thread *thread2) -{ - return btp_thread_cmp(thread1, thread2); -} - -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/abrt-action-analyze-backtrace.c b/src/plugins/abrt-action-analyze-backtrace.c index a980213..9348195 100644 --- a/src/plugins/abrt-action-analyze-backtrace.c +++ b/src/plugins/abrt-action-analyze-backtrace.c @@ -15,7 +15,11 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "satyr-compat.h" +#include <satyr/location.h> +#include <satyr/thread.h> +#include <satyr/gdb/frame.h> +#include <satyr/gdb/stacktrace.h> + #include "libabrt.h"
static const char *dump_dir_name = "."; @@ -130,18 +134,29 @@ int main(int argc, char **argv) }
/* Compute duplication hash. */ - 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); - - VERB3 log("Generating duphash: %s", str_hash->buf); - char hash_str[SHA1_RESULT_LEN*2 + 1]; - create_hash(hash_str, str_hash->buf); - - dd_save_text(dd, FILENAME_DUPHASH, hash_str); - strbuf_free(str_hash); - free(str_hash_core); + struct sr_thread *crash_thread = + (struct sr_thread *)sr_gdb_stacktrace_find_crash_thread(backtrace); + + if (crash_thread) + { + char *hash_str; + + if (g_verbose >= 3) + { + hash_str = sr_thread_get_duphash(crash_thread, 3, component, + SR_DUPHASH_NOHASH); + log("Generating duphash: %s", hash_str); + free(hash_str); + } + + hash_str = sr_thread_get_duphash(crash_thread, 3, component, + SR_DUPHASH_NORMAL); + dd_save_text(dd, FILENAME_DUPHASH, hash_str); + free(hash_str); + } + else + log(_("Crash thread not found")); +
/* Compute the backtrace rating. */ float quality = sr_gdb_stacktrace_quality_complex(backtrace); diff --git a/src/plugins/abrt-action-generate-core-backtrace.c b/src/plugins/abrt-action-generate-core-backtrace.c index 24d69cb..a549a53 100644 --- a/src/plugins/abrt-action-generate-core-backtrace.c +++ b/src/plugins/abrt-action-generate-core-backtrace.c @@ -16,74 +16,10 @@ with this program; if not, write to the Free Software Foundation, Inc., 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 <satyr/abrt.h> +#include <satyr/utils.h>
-#include <btparser/hash_sha1.h> -#include <btparser/utils.h> -#include <btparser/core-backtrace.h> -#include <btparser/core-backtrace-python.h> -#include <btparser/core-backtrace-oops.h> - -static bool raw_fingerprints = false; - -/* add the information about '?' flag to fingerprint field - fingerprint is otherwise always empty for kerneloops */ -static void oops_add_question_marks(GList *backtrace) -{ - GList *elem = backtrace; - struct backtrace_entry *entry; - while (elem) - { - entry = (struct backtrace_entry *)elem->data; - if (entry->function_initial_loc) - entry->fingerprint = btp_strdup("?"); - - elem = g_list_next(elem); - } -} - -static void hash_fingerprints(GList *backtrace) -{ - GList *elem = backtrace; - struct backtrace_entry *entry; - char bin_hash[BTP_SHA1_RESULT_BIN_LEN], hash[BTP_SHA1_RESULT_LEN]; - btp_sha1_ctx_t ctx; - while (elem) - { - entry = (struct backtrace_entry *)elem->data; - if (entry->fingerprint) - { - btp_sha1_begin(&ctx); - btp_sha1_hash(&ctx, entry->fingerprint, strlen(entry->fingerprint)); - btp_sha1_end(&ctx, bin_hash); - btp_bin2hex(hash, bin_hash, sizeof(bin_hash))[0] = '\0'; - - free(entry->fingerprint); - entry->fingerprint = btp_strndup(hash, sizeof(hash)); - } - elem = g_list_next(elem); - } -} +#include "libabrt.h"
int main(int argc, char **argv) { @@ -97,12 +33,11 @@ int main(int argc, char **argv) abrt_init(argv);
const char *dump_dir_name = "."; - /* 60 seconds was too limiting on slow machines */ - const int exec_timeout_sec = 240; + bool raw_fingerprints = false;
/* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( - "& [-v] -d DIR\n" + "& [-v] [-r] -d DIR\n" "\n" "Creates coredump-level backtrace from core dump and corresponding binary" ); @@ -123,109 +58,22 @@ int main(int argc, char **argv) export_abrt_envvars(0);
if (g_verbose > 1) - btp_debug_parser = true; + sr_debug_parser = true;
/* Let user know what's going on */ log(_("Generating core_backtrace"));
- /* Get the executable name -- unstrip doesn't know it. */ - struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY); - if (!dd) - xfunc_die(); /* dd_opendir already printed error msg */ - char *analyzer = dd_load_text(dd, FILENAME_ANALYZER); - char *executable = dd_load_text_ext(dd, FILENAME_EXECUTABLE, - DD_FAIL_QUIETLY_ENOENT); - char *txt_backtrace = dd_load_text_ext(dd, FILENAME_BACKTRACE, - DD_FAIL_QUIETLY_ENOENT); - char *kernel = dd_load_text_ext(dd, FILENAME_KERNEL, - DD_FAIL_QUIETLY_ENOENT | - DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); - dd_close(dd); - - /* Parse addresses and eventual symbols from the output */ - GList *backtrace; - if (strcmp(analyzer, "CCpp") == 0) - { - char *gdb_out = get_backtrace(dump_dir_name, exec_timeout_sec, NULL); - if (gdb_out == NULL) - xfunc_die(); - - /* We observed a case when we were stuck for 36 minutes after emitting - * "Generating backtrace" message (in get_backtrace). - * We don't know whether we finished bt generation - * and were stuck somewhere below this point, or we were stuck - * in get_backtrace(). For now, we emit this message - * even in non-verbose mode to aid in future debugging: - */ - log(_("Backtrace is generated, %u bytes"), (int)strlen(gdb_out)); - - backtrace = btp_backtrace_extract_addresses(gdb_out); - VERB1 log("Extracted %d frames from the backtrace", g_list_length(backtrace)); - free(gdb_out); + char *error_message = NULL; + bool success = sr_abrt_create_core_stacktrace(dump_dir_name, + !raw_fingerprints, + &error_message);
- VERB1 log("Running eu-unstrip -n to obtain build ids"); - /* Run eu-unstrip -n to obtain the ids. This should be rewritten to read - * them directly from the core. */ - char *unstrip_output = run_unstrip_n(dump_dir_name, /*timeout_sec:*/ 30); - if (unstrip_output == NULL) - error_msg_and_die("Running eu-unstrip failed"); - btp_core_assign_build_ids(backtrace, unstrip_output, executable); - free(unstrip_output); - - /* Remove empty lines from the backtrace. */ - GList *loop = backtrace; - while (loop != NULL) - { - struct backtrace_entry *entry = loop->data; - GList *const tmp_next = g_list_next(loop); - if (!entry->build_id && !entry->filename && !entry->modname) - backtrace = g_list_delete_link(backtrace, loop); - loop = tmp_next; - } - - /* Extract address ranges from all the executables in the backtrace */ - VERB1 log("Computing function fingerprints"); - btp_core_backtrace_fingerprint(backtrace); - if (!raw_fingerprints) - hash_fingerprints(backtrace); - } - else if (strcmp(analyzer, "Python") == 0) - backtrace = btp_parse_python_backtrace(txt_backtrace); - else if (strcmp(analyzer, "Kerneloops") == 0 || strcmp(analyzer, "vmcore") == 0) + if (!success) { - /* btp_parse_kerneloops() accepts NULL in the kernelver argument. It is not - * documented, but it is true. */ - if (kernel != NULL) - { - char *space = strchr(kernel, ' '); - if (space) - *space = '\0'; - } - - backtrace = btp_parse_kerneloops(txt_backtrace, kernel); - oops_add_question_marks(backtrace); + log(_("Error: %s"), error_message); + free(error_message); + return 1; } - else - error_msg_and_die(_("Core-backtraces are not supported for '%s'"), analyzer); - - free(txt_backtrace); - free(kernel); - free(executable); - free(analyzer);
- char *formatted_backtrace = btp_core_backtrace_fmt(backtrace); - - dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (!dd) - xfunc_die(); - dd_save_text(dd, FILENAME_CORE_BACKTRACE, formatted_backtrace); - dd_close(dd); - - log(_("Core backtrace is generated and saved, %u bytes"), (int)strlen(formatted_backtrace)); - - free(formatted_backtrace); - btp_core_backtrace_free(backtrace); return 0; } - -#endif /* USE_SATYR */ diff --git a/src/plugins/koops_event.conf b/src/plugins/koops_event.conf index 7409922..9966775 100644 --- a/src/plugins/koops_event.conf +++ b/src/plugins/koops_event.conf @@ -3,7 +3,6 @@ EVENT=post-create analyzer=Kerneloops # >> instead of > is due to bugzilla.redhat.com/show_bug.cgi?id=854266 abrt-action-analyze-oops && dmesg >>dmesg && - abrt-action-generate-core-backtrace abrt-action-save-kernel-data
# If you want behavior similar to one provided by kerneloops daemon diff --git a/src/plugins/python_event.conf b/src/plugins/python_event.conf index 1aa0e99..3a45373 100644 --- a/src/plugins/python_event.conf +++ b/src/plugins/python_event.conf @@ -8,7 +8,6 @@ EVENT=post-create analyzer=Python exit 1 fi abrt-action-analyze-python - abrt-action-generate-core-backtrace
EVENT=report_Bugzilla analyzer=Python component!=anaconda test -f component || abrt-action-save-package-data diff --git a/src/plugins/vmcore_event.conf b/src/plugins/vmcore_event.conf index f6e260e..5d2d099 100644 --- a/src/plugins/vmcore_event.conf +++ b/src/plugins/vmcore_event.conf @@ -2,7 +2,6 @@ EVENT=analyze_VMcore analyzer=vmcore abrt-action-analyze-vmcore && abrt-action-analyze-oops && - abrt-action-generate-core-backtrace && abrt-action-save-kernel-data
# If you want behavior similar to one provided by kerneloops daemon
Signed-off-by: Martin Milata mmilata@redhat.com --- abrt.spec.in | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/abrt.spec.in b/abrt.spec.in index cff4338..09fa9b4 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -62,9 +62,7 @@ BuildRequires: asciidoc BuildRequires: doxygen BuildRequires: xmlto BuildRequires: libreport-devel >= 2.1.3 -BuildRequires: btparser-devel -##satyr migration: -#BuildRequires: satyr-devel +BuildRequires: satyr-devel Requires: libreport >= 2.1.3 # these only exist on suse %if 0%{?suse_version} @@ -123,9 +121,7 @@ GTK+ wizard for convenient bug reporting. %package addon-ccpp Summary: %{name}'s C/C++ addon Group: System Environment/Libraries -Requires: cpio, btparser -##satyr migration: -#Requires: cpio, satyr +Requires: cpio, satyr Requires: gdb >= 7.0-3 Requires: elfutils # abrt-action-perform-ccpp-analysis wants to run analyze_RetraceServer:
Related to abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com --- configure.ac | 18 +-- libreport-web.pc.in | 2 +- src/lib/json.c | 288 +--------------------------------------- src/plugins/reporter-bugzilla.c | 75 ++++------- 4 files changed, 28 insertions(+), 355 deletions(-)
diff --git a/configure.ac b/configure.ac index 671d6a4..da7f480 100644 --- a/configure.ac +++ b/configure.ac @@ -145,11 +145,6 @@ 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([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) @@ -158,18 +153,7 @@ PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([PROXY], [libproxy-1.0], [ AC_DEFINE([HAVE_PROXY], [1], [Use libproxy]) ], [:]) - -[if test "$with_satyr" = "yes"] -[then] - PKG_CHECK_MODULES([SATYR], [satyr]) - AC_DEFINE([USE_SATYR], [1], [Use satyr instead of btparser]) - SATYR_PKG="satyr" -[else] - PKG_CHECK_MODULES([SATYR], [btparser]) - SATYR_PKG="btparser" -[fi] -AC_SUBST(SATYR_PKG) -AM_CONDITIONAL([USE_SATYR], [test "$with_satyr" = "yes"]) +PKG_CHECK_MODULES([SATYR], [satyr])
AC_ARG_WITH(newt, AS_HELP_STRING([--with-newt],[use newt (default is YES)]), diff --git a/libreport-web.pc.in b/libreport-web.pc.in index ec4ab8e..288e613 100644 --- a/libreport-web.pc.in +++ b/libreport-web.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libreport Description: Library providing network API for libreport Version: @VERSION@ -Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json @SATYR_PKG@ libreport +Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json satyr libreport Libs: -L${libdir} -lreport-web Cflags:
diff --git a/src/lib/json.c b/src/lib/json.c index d5c6f2d..68348ad 100644 --- a/src/lib/json.c +++ b/src/lib/json.c @@ -19,6 +19,9 @@
#include <json/json.h>
+#include <satyr/abrt.h> +#include <satyr/report.h> + #include "internal_libreport.h" #include "ureport.h" #include "libreport_curl.h" @@ -34,11 +37,6 @@ static void ureport_add_str(struct json_object *ur, const char *key, json_object_object_add(ur, key, jstring); }
-#if USE_SATYR - -#include <satyr/abrt.h> -#include <satyr/report.h> - char *ureport_from_dump_dir(const char *dump_dir_path) { char *error_message; @@ -54,286 +52,6 @@ char *ureport_from_dump_dir(const char *dump_dir_path) return json_ureport; }
-#else /* USE_SATYR */ - -#include <btparser/thread.h> -#include <btparser/core-backtrace.h> - -/* on success 1 returned, on error zero is returned and appropriate value - * is returned as third argument. You should never read third argument when - * function fails - * - * json-c library doesn't have any json_object_new_long, - * thus we have to use only int - */ -static int get_pd_int_item(problem_data_t *pd, const char *key, int *result) -{ - if (!pd || !key) - return 0; - - char *pd_item = problem_data_get_content_or_NULL(pd, key); - if (!pd_item) - { - VERB1 log("warning: '%s' is not an item in problem directory", key); - return 0; - } - - errno = 0; - char *e; - long i = strtol(pd_item, &e, 10); - if (errno || pd_item == e || *e != '\0' || (int) i != i) - return 0; - - *result = i; - return 1; -} - -static void ureport_add_int(struct json_object *ur, const char *key, int i) -{ - struct json_object *jint = json_object_new_int(i); - if (!jint) - die_out_of_memory(); - - json_object_object_add(ur, key, jint); -} - -static void ureport_add_os(struct json_object *ur, problem_data_t *pd) -{ - char *name; - char *version; - map_string_t *osinfo = new_map_string(); - problem_data_get_osinfo(pd, osinfo); - parse_osinfo_for_rhts(osinfo, &name, &version); - free_map_string(osinfo); - - if (!name || !version) - { - free(name); - free(version); - return; - } - - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_str(jobject, "name", name); - ureport_add_str(jobject, "version", version); - - free(name); - free(version); - - json_object_object_add(ur, "os", jobject); -} - -static bool ureport_add_type(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); - if (!pd_item) - { - error_msg(_("Missing problem element '%s'"), FILENAME_ANALYZER); - return false; - } - - if (strcmp(pd_item, "CCpp") == 0) - ureport_add_str(ur, "type", "USERSPACE"); - else if (strcmp(pd_item, "Python") == 0) - ureport_add_str(ur, "type", "PYTHON"); - else if (strcmp(pd_item, "Kerneloops") == 0 || strcmp(pd_item, "vmcore") == 0) - ureport_add_str(ur, "type", "KERNELOOPS"); - else - { - error_msg(_("An unsupported value '%s' in problem element '%s'"), pd_item, FILENAME_ANALYZER); - return false; - } - - return true; -} - -static void ureport_add_core_backtrace(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_CORE_BACKTRACE); - if (!pd_item) - return; - - struct btp_thread *core_bt = btp_load_core_backtrace(pd_item); - if (!core_bt) - return; - - struct json_object *jarray = json_object_new_array(); - if (!jarray) - die_out_of_memory(); - - struct btp_frame *frame; - unsigned frame_nr = 0; - for (frame = core_bt->frames; frame; frame = frame->next) - { - struct frame_aux *aux = frame->user_data; - - struct json_object *item = json_object_new_object(); - if (!item) - die_out_of_memory(); - - if (aux->filename) - ureport_add_str(item, "path", aux->filename); - - if (frame->function_name) - ureport_add_str(item, "funcname", frame->function_name); - - if (aux->build_id) - ureport_add_str(item, "buildid", aux->build_id); - - if (aux->fingerprint) - ureport_add_str(item, "funchash", aux->fingerprint); - - /* always add offset - even offset 0 is valid */ - ureport_add_int(item, "offset", (uintmax_t)frame->address); - - ureport_add_int(item, "frame", frame_nr++); - ureport_add_int(item, "thread", 0); - - - json_object_array_add(jarray, item); - } - - btp_thread_free(core_bt); - - json_object_object_add(ur, FILENAME_CORE_BACKTRACE, jarray); -} -static void ureport_add_item_str(struct json_object *ur, problem_data_t *pd, - const char *key, const char *rename) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, key); - if (!pd_item) - return; - - ureport_add_str(ur, (rename) ?: key, pd_item); -} - -static void ureport_add_item_int(struct json_object *ur, problem_data_t *pd, - const char *key, const char *rename) -{ - int nr; - int stat = get_pd_int_item(pd, key, &nr); - if (!stat) - return; - - ureport_add_int(ur, (rename) ?: key, nr); -} - -static void ureport_add_pkg(struct json_object *ur, problem_data_t *pd) -{ - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_item_int(jobject, pd, FILENAME_PKG_EPOCH, "epoch"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_NAME, "name"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_VERSION, "version"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_RELEASE, "release"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_ARCH, "architecture"); - - json_object_object_add(ur, "installed_package", jobject); -} - -static void ureport_add_related_pkgs(struct json_object *ur, problem_data_t *pd) -{ - // TODO: populate this field - struct json_object *jobject = json_object_new_array(); - json_object_object_add(ur, "related_packages", jobject); -} - -static void ureport_add_reporter(struct json_object *ur, const char *name, const char *version) -{ - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_str(jobject, "name", name); - ureport_add_str(jobject, "version", version); - - json_object_object_add(ur, "reporter", jobject); -} - -static void ureport_add_oops(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); - if (!pd_item) - return; - - if (!strcmp(pd_item, "Kerneloops")) - ureport_add_item_str(ur, pd, FILENAME_BACKTRACE, "oops"); -} - -char *new_json_ureport(problem_data_t *pd) -{ - struct json_object *ureport = json_object_new_object(); - if (!ureport) - die_out_of_memory(); - - ureport_add_item_str(ureport, pd, "user_type", NULL); - ureport_add_item_int(ureport, pd, "uptime", NULL); - - /* mandatory, but not in problem-dir - * - * ureport_add_item_int(ureport, pd, "crash_thread", NULL); - */ - ureport_add_int(ureport, "ureport_version", 1); - ureport_add_int(ureport, "crash_thread", 0); - - ureport_add_item_str(ureport, pd, FILENAME_ARCHITECTURE, NULL); - ureport_add_item_str(ureport, pd, FILENAME_EXECUTABLE, NULL); - ureport_add_item_str(ureport, pd, FILENAME_REASON, NULL); - ureport_add_item_str(ureport, pd, FILENAME_COMPONENT, NULL); - - if (!ureport_add_type(ureport, pd)) - { - error_msg(_("Can't create an uReport without 'type'")); - json_object_put(ureport); - return NULL; - } - - ureport_add_pkg(ureport, pd); - ureport_add_related_pkgs(ureport, pd); - ureport_add_os(ureport, pd); - - ureport_add_core_backtrace(ureport, pd); - ureport_add_reporter(ureport, "ABRT", VERSION); - - ureport_add_oops(ureport, pd); - - char *j = xstrdup(json_object_to_json_string(ureport)); - json_object_put(ureport); - - return j; -} - -char *ureport_from_dump_dir(const char *dump_dir_path) -{ - struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY); - if (!dd) - xfunc_die(); - - problem_data_t *pd = create_problem_data_from_dump_dir(dd); - - dd_close(dd); - if (!pd) - xfunc_die(); /* create_problem_data_from_dump_dir already emitted error msg */ - - char *json_ureport = new_json_ureport(pd); - problem_data_free(pd); - - if (json_ureport == NULL) - { - error_msg(_("Not uploading an empty uReport")); - return NULL; - } - - return json_ureport; -} - -#endif /* USE_SATYR */ - char *new_json_attachment(const char *bthash, const char *type, const char *data) { struct json_object *attachment = json_object_new_object(); diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c index 626b41f..7175e1f 100644 --- a/src/plugins/reporter-bugzilla.c +++ b/src/plugins/reporter-bugzilla.c @@ -21,39 +21,8 @@ #include "abrt_xmlrpc.h" #include "rhbz.h"
-/* btparser compatibility - once we move to satyr, the else branch of the ifdef - * can be removed - */ -#ifdef USE_SATYR - -#include <satyr/location.h> -#include <satyr/gdb_stacktrace.h> -#include <satyr/gdb_thread.h> -#include <satyr/gdb_frame.h> -#include <satyr/strbuf.h> - -#else /* USE_SATYR */ - -#include <btparser/location.h> -#include <btparser/backtrace.h> -#include <btparser/thread.h> -#include <btparser/frame.h> -#include <btparser/strbuf.h> - -#define sr_location btp_location -#define sr_location_init btp_location_init -#define sr_gdb_stacktrace btp_backtrace -#define sr_gdb_stacktrace_parse btp_backtrace_parse -#define sr_gdb_stacktrace_get_optimized_thread btp_backtrace_get_optimized_thread -#define sr_gdb_stacktrace_free btp_backtrace_free -#define sr_gdb_thread btp_thread -#define sr_gdb_thread_append_to_str btp_thread_append_to_str -#define sr_gdb_thread_free btp_thread_free -#define sr_strbuf btp_strbuf -#define sr_strbuf_new btp_strbuf_new -#define sr_strbuf_free_nobuf btp_strbuf_free_nobuf - -#endif /* USE_SATYR */ +#include <satyr/stacktrace.h> +#include <satyr/abrt.h>
struct section_t { char *name; @@ -365,38 +334,40 @@ int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data,
if (strlen(item->content) >= max_text_size) { - struct sr_location location; - sr_location_init(&location); + char *error_msg = NULL; + const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER); + if (!analyzer) + return 0; + + /* For CCpp crashes, use the GDB-produced backtrace which should be + * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE + * by default for CCpp crashes. + */ + enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer); + if (strcmp(analyzer, "CCpp") == 0) + report_type = SR_REPORT_GDB;
- /* sr_gdb_stacktrace_parse modifies the input parameter */ + /* sr_stacktrace_parse modifies the input parameter */ char *content = item->content; - struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location); + struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type, + (const char **)&content, &error_msg);
if (!backtrace) { - log(_("Can't parse backtrace")); + log(_("Can't parse backtrace: %s"), error_msg); + free(error_msg); return 0; }
/* Get optimized thread stack trace for 10 top most frames */ - struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10); - - sr_gdb_stacktrace_free(backtrace); + truncated = sr_stacktrace_to_short_text(backtrace, 10); + sr_stacktrace_free(backtrace);
- if (!thread) + if (!truncated) { - log(_("Can't find crash thread")); + log(_("Can't generate stacktrace description (no crash thread?)")); return 0; } - - /* Cannot be NULL, it dies on memory error */ - struct sr_strbuf *bt = sr_strbuf_new(); - - sr_gdb_thread_append_to_str(thread, bt, true); - - sr_gdb_thread_free(thread); - - truncated = sr_strbuf_free_nobuf(bt); }
append_text(result,
Signed-off-by: Martin Milata mmilata@redhat.com --- libreport.spec.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/libreport.spec.in b/libreport.spec.in index ba3465b..4794909 100644 --- a/libreport.spec.in +++ b/libreport.spec.in @@ -40,12 +40,10 @@ BuildRequires: asciidoc BuildRequires: xmlto BuildRequires: newt-devel BuildRequires: libproxy-devel -BuildRequires: btparser-devel +BuildRequires: satyr-devel >= 0.4 %if %{with bugzilla} BuildRequires: xmlrpc-c-devel %endif -##satyr migration: -#BuildRequires: satyr-devel BuildRequires: doxygen Requires: libreport-filesystem = %{version}-%{release} # required for update from old report library, otherwise we obsolete report-gtk @@ -53,6 +51,7 @@ Requires: libreport-filesystem = %{version}-%{release} # end-up with: can't import report.GtkIO # FIXME: can be removed when F15 will EOLed, needs to stay in rhel6! Requires: libreport-python +Requires: satyr >= 0.4
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Related to abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com --- configure.ac | 18 +-- libreport-web.pc.in | 2 +- src/lib/json.c | 288 +--------------------------------------- src/plugins/reporter-bugzilla.c | 75 +++-------- 4 files changed, 27 insertions(+), 356 deletions(-)
diff --git a/configure.ac b/configure.ac index 671d6a4..da7f480 100644 --- a/configure.ac +++ b/configure.ac @@ -145,11 +145,6 @@ 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([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) @@ -158,18 +153,7 @@ PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([PROXY], [libproxy-1.0], [ AC_DEFINE([HAVE_PROXY], [1], [Use libproxy]) ], [:]) - -[if test "$with_satyr" = "yes"] -[then] - PKG_CHECK_MODULES([SATYR], [satyr]) - AC_DEFINE([USE_SATYR], [1], [Use satyr instead of btparser]) - SATYR_PKG="satyr" -[else] - PKG_CHECK_MODULES([SATYR], [btparser]) - SATYR_PKG="btparser" -[fi] -AC_SUBST(SATYR_PKG) -AM_CONDITIONAL([USE_SATYR], [test "$with_satyr" = "yes"]) +PKG_CHECK_MODULES([SATYR], [satyr])
AC_ARG_WITH(newt, AS_HELP_STRING([--with-newt],[use newt (default is YES)]), diff --git a/libreport-web.pc.in b/libreport-web.pc.in index ec4ab8e..288e613 100644 --- a/libreport-web.pc.in +++ b/libreport-web.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libreport Description: Library providing network API for libreport Version: @VERSION@ -Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json @SATYR_PKG@ libreport +Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json satyr libreport Libs: -L${libdir} -lreport-web Cflags:
diff --git a/src/lib/json.c b/src/lib/json.c index d5c6f2d..68348ad 100644 --- a/src/lib/json.c +++ b/src/lib/json.c @@ -19,6 +19,9 @@
#include <json/json.h>
+#include <satyr/abrt.h> +#include <satyr/report.h> + #include "internal_libreport.h" #include "ureport.h" #include "libreport_curl.h" @@ -34,11 +37,6 @@ static void ureport_add_str(struct json_object *ur, const char *key, json_object_object_add(ur, key, jstring); }
-#if USE_SATYR - -#include <satyr/abrt.h> -#include <satyr/report.h> - char *ureport_from_dump_dir(const char *dump_dir_path) { char *error_message; @@ -54,286 +52,6 @@ char *ureport_from_dump_dir(const char *dump_dir_path) return json_ureport; }
-#else /* USE_SATYR */ - -#include <btparser/thread.h> -#include <btparser/core-backtrace.h> - -/* on success 1 returned, on error zero is returned and appropriate value - * is returned as third argument. You should never read third argument when - * function fails - * - * json-c library doesn't have any json_object_new_long, - * thus we have to use only int - */ -static int get_pd_int_item(problem_data_t *pd, const char *key, int *result) -{ - if (!pd || !key) - return 0; - - char *pd_item = problem_data_get_content_or_NULL(pd, key); - if (!pd_item) - { - VERB1 log("warning: '%s' is not an item in problem directory", key); - return 0; - } - - errno = 0; - char *e; - long i = strtol(pd_item, &e, 10); - if (errno || pd_item == e || *e != '\0' || (int) i != i) - return 0; - - *result = i; - return 1; -} - -static void ureport_add_int(struct json_object *ur, const char *key, int i) -{ - struct json_object *jint = json_object_new_int(i); - if (!jint) - die_out_of_memory(); - - json_object_object_add(ur, key, jint); -} - -static void ureport_add_os(struct json_object *ur, problem_data_t *pd) -{ - char *name; - char *version; - map_string_t *osinfo = new_map_string(); - problem_data_get_osinfo(pd, osinfo); - parse_osinfo_for_rhts(osinfo, &name, &version); - free_map_string(osinfo); - - if (!name || !version) - { - free(name); - free(version); - return; - } - - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_str(jobject, "name", name); - ureport_add_str(jobject, "version", version); - - free(name); - free(version); - - json_object_object_add(ur, "os", jobject); -} - -static bool ureport_add_type(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); - if (!pd_item) - { - error_msg(_("Missing problem element '%s'"), FILENAME_ANALYZER); - return false; - } - - if (strcmp(pd_item, "CCpp") == 0) - ureport_add_str(ur, "type", "USERSPACE"); - else if (strcmp(pd_item, "Python") == 0) - ureport_add_str(ur, "type", "PYTHON"); - else if (strcmp(pd_item, "Kerneloops") == 0 || strcmp(pd_item, "vmcore") == 0) - ureport_add_str(ur, "type", "KERNELOOPS"); - else - { - error_msg(_("An unsupported value '%s' in problem element '%s'"), pd_item, FILENAME_ANALYZER); - return false; - } - - return true; -} - -static void ureport_add_core_backtrace(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_CORE_BACKTRACE); - if (!pd_item) - return; - - struct btp_thread *core_bt = btp_load_core_backtrace(pd_item); - if (!core_bt) - return; - - struct json_object *jarray = json_object_new_array(); - if (!jarray) - die_out_of_memory(); - - struct btp_frame *frame; - unsigned frame_nr = 0; - for (frame = core_bt->frames; frame; frame = frame->next) - { - struct frame_aux *aux = frame->user_data; - - struct json_object *item = json_object_new_object(); - if (!item) - die_out_of_memory(); - - if (aux->filename) - ureport_add_str(item, "path", aux->filename); - - if (frame->function_name) - ureport_add_str(item, "funcname", frame->function_name); - - if (aux->build_id) - ureport_add_str(item, "buildid", aux->build_id); - - if (aux->fingerprint) - ureport_add_str(item, "funchash", aux->fingerprint); - - /* always add offset - even offset 0 is valid */ - ureport_add_int(item, "offset", (uintmax_t)frame->address); - - ureport_add_int(item, "frame", frame_nr++); - ureport_add_int(item, "thread", 0); - - - json_object_array_add(jarray, item); - } - - btp_thread_free(core_bt); - - json_object_object_add(ur, FILENAME_CORE_BACKTRACE, jarray); -} -static void ureport_add_item_str(struct json_object *ur, problem_data_t *pd, - const char *key, const char *rename) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, key); - if (!pd_item) - return; - - ureport_add_str(ur, (rename) ?: key, pd_item); -} - -static void ureport_add_item_int(struct json_object *ur, problem_data_t *pd, - const char *key, const char *rename) -{ - int nr; - int stat = get_pd_int_item(pd, key, &nr); - if (!stat) - return; - - ureport_add_int(ur, (rename) ?: key, nr); -} - -static void ureport_add_pkg(struct json_object *ur, problem_data_t *pd) -{ - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_item_int(jobject, pd, FILENAME_PKG_EPOCH, "epoch"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_NAME, "name"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_VERSION, "version"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_RELEASE, "release"); - ureport_add_item_str(jobject, pd, FILENAME_PKG_ARCH, "architecture"); - - json_object_object_add(ur, "installed_package", jobject); -} - -static void ureport_add_related_pkgs(struct json_object *ur, problem_data_t *pd) -{ - // TODO: populate this field - struct json_object *jobject = json_object_new_array(); - json_object_object_add(ur, "related_packages", jobject); -} - -static void ureport_add_reporter(struct json_object *ur, const char *name, const char *version) -{ - struct json_object *jobject = json_object_new_object(); - if (!jobject) - die_out_of_memory(); - - ureport_add_str(jobject, "name", name); - ureport_add_str(jobject, "version", version); - - json_object_object_add(ur, "reporter", jobject); -} - -static void ureport_add_oops(struct json_object *ur, problem_data_t *pd) -{ - char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); - if (!pd_item) - return; - - if (!strcmp(pd_item, "Kerneloops")) - ureport_add_item_str(ur, pd, FILENAME_BACKTRACE, "oops"); -} - -char *new_json_ureport(problem_data_t *pd) -{ - struct json_object *ureport = json_object_new_object(); - if (!ureport) - die_out_of_memory(); - - ureport_add_item_str(ureport, pd, "user_type", NULL); - ureport_add_item_int(ureport, pd, "uptime", NULL); - - /* mandatory, but not in problem-dir - * - * ureport_add_item_int(ureport, pd, "crash_thread", NULL); - */ - ureport_add_int(ureport, "ureport_version", 1); - ureport_add_int(ureport, "crash_thread", 0); - - ureport_add_item_str(ureport, pd, FILENAME_ARCHITECTURE, NULL); - ureport_add_item_str(ureport, pd, FILENAME_EXECUTABLE, NULL); - ureport_add_item_str(ureport, pd, FILENAME_REASON, NULL); - ureport_add_item_str(ureport, pd, FILENAME_COMPONENT, NULL); - - if (!ureport_add_type(ureport, pd)) - { - error_msg(_("Can't create an uReport without 'type'")); - json_object_put(ureport); - return NULL; - } - - ureport_add_pkg(ureport, pd); - ureport_add_related_pkgs(ureport, pd); - ureport_add_os(ureport, pd); - - ureport_add_core_backtrace(ureport, pd); - ureport_add_reporter(ureport, "ABRT", VERSION); - - ureport_add_oops(ureport, pd); - - char *j = xstrdup(json_object_to_json_string(ureport)); - json_object_put(ureport); - - return j; -} - -char *ureport_from_dump_dir(const char *dump_dir_path) -{ - struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY); - if (!dd) - xfunc_die(); - - problem_data_t *pd = create_problem_data_from_dump_dir(dd); - - dd_close(dd); - if (!pd) - xfunc_die(); /* create_problem_data_from_dump_dir already emitted error msg */ - - char *json_ureport = new_json_ureport(pd); - problem_data_free(pd); - - if (json_ureport == NULL) - { - error_msg(_("Not uploading an empty uReport")); - return NULL; - } - - return json_ureport; -} - -#endif /* USE_SATYR */ - char *new_json_attachment(const char *bthash, const char *type, const char *data) { struct json_object *attachment = json_object_new_object(); diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c index 626b41f..972a1f0 100644 --- a/src/plugins/reporter-bugzilla.c +++ b/src/plugins/reporter-bugzilla.c @@ -21,39 +21,8 @@ #include "abrt_xmlrpc.h" #include "rhbz.h"
-/* btparser compatibility - once we move to satyr, the else branch of the ifdef - * can be removed - */ -#ifdef USE_SATYR - -#include <satyr/location.h> -#include <satyr/gdb_stacktrace.h> -#include <satyr/gdb_thread.h> -#include <satyr/gdb_frame.h> -#include <satyr/strbuf.h> - -#else /* USE_SATYR */ - -#include <btparser/location.h> -#include <btparser/backtrace.h> -#include <btparser/thread.h> -#include <btparser/frame.h> -#include <btparser/strbuf.h> - -#define sr_location btp_location -#define sr_location_init btp_location_init -#define sr_gdb_stacktrace btp_backtrace -#define sr_gdb_stacktrace_parse btp_backtrace_parse -#define sr_gdb_stacktrace_get_optimized_thread btp_backtrace_get_optimized_thread -#define sr_gdb_stacktrace_free btp_backtrace_free -#define sr_gdb_thread btp_thread -#define sr_gdb_thread_append_to_str btp_thread_append_to_str -#define sr_gdb_thread_free btp_thread_free -#define sr_strbuf btp_strbuf -#define sr_strbuf_new btp_strbuf_new -#define sr_strbuf_free_nobuf btp_strbuf_free_nobuf - -#endif /* USE_SATYR */ +#include <satyr/stacktrace.h> +#include <satyr/abrt.h>
struct section_t { char *name; @@ -365,38 +334,38 @@ int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data,
if (strlen(item->content) >= max_text_size) { - struct sr_location location; - sr_location_init(&location); + char *error_msg = NULL; + const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER); + if (!analyzer) + return 0; + + /* For CCpp crashes, use the GDB-produced backtrace which should be + * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE + * by default for CCpp crashes. + */ + enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer); + if (strcmp(analyzer, "CCpp") == 0) + report_type = SR_REPORT_GDB;
- /* sr_gdb_stacktrace_parse modifies the input parameter */ - char *content = item->content; - struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location); + struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type, + item->content, &error_msg);
if (!backtrace) { - log(_("Can't parse backtrace")); + log(_("Can't parse backtrace: %s"), error_msg); + free(error_msg); return 0; }
/* Get optimized thread stack trace for 10 top most frames */ - struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10); - - sr_gdb_stacktrace_free(backtrace); + truncated = sr_stacktrace_to_short_text(backtrace, 10); + sr_stacktrace_free(backtrace);
- if (!thread) + if (!truncated) { - log(_("Can't find crash thread")); + log(_("Can't generate stacktrace description (no crash thread?)")); return 0; } - - /* Cannot be NULL, it dies on memory error */ - struct sr_strbuf *bt = sr_strbuf_new(); - - sr_gdb_thread_append_to_str(thread, bt, true); - - sr_gdb_thread_free(thread); - - truncated = sr_strbuf_free_nobuf(bt); }
append_text(result,
Signed-off-by: Martin Milata mmilata@redhat.com --- libreport.spec.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/libreport.spec.in b/libreport.spec.in index ba3465b..4794909 100644 --- a/libreport.spec.in +++ b/libreport.spec.in @@ -40,12 +40,10 @@ BuildRequires: asciidoc BuildRequires: xmlto BuildRequires: newt-devel BuildRequires: libproxy-devel -BuildRequires: btparser-devel +BuildRequires: satyr-devel >= 0.4 %if %{with bugzilla} BuildRequires: xmlrpc-c-devel %endif -##satyr migration: -#BuildRequires: satyr-devel BuildRequires: doxygen Requires: libreport-filesystem = %{version}-%{release} # required for update from old report library, otherwise we obsolete report-gtk @@ -53,6 +51,7 @@ Requires: libreport-filesystem = %{version}-%{release} # end-up with: can't import report.GtkIO # FIXME: can be removed when F15 will EOLed, needs to stay in rhel6! Requires: libreport-python +Requires: satyr >= 0.4
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Reporting works fine with these patches (except reporter-ureport). Pushed both. Thank you!
On Tue, 2013-07-09 at 18:26 +0200, Martin Milata wrote:
Related to abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com
configure.ac | 18 +-- libreport-web.pc.in | 2 +- src/lib/json.c | 288 +--------------------------------------- src/plugins/reporter-bugzilla.c | 75 +++-------- 4 files changed, 27 insertions(+), 356 deletions(-)
diff --git a/configure.ac b/configure.ac index 671d6a4..da7f480 100644 --- a/configure.ac +++ b/configure.ac @@ -145,11 +145,6 @@ 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([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) @@ -158,18 +153,7 @@ PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([PROXY], [libproxy-1.0], [ AC_DEFINE([HAVE_PROXY], [1], [Use libproxy]) ], [:])
-[if test "$with_satyr" = "yes"] -[then]
- PKG_CHECK_MODULES([SATYR], [satyr])
- AC_DEFINE([USE_SATYR], [1], [Use satyr instead of btparser])
- SATYR_PKG="satyr"
-[else]
- PKG_CHECK_MODULES([SATYR], [btparser])
- SATYR_PKG="btparser"
-[fi] -AC_SUBST(SATYR_PKG) -AM_CONDITIONAL([USE_SATYR], [test "$with_satyr" = "yes"]) +PKG_CHECK_MODULES([SATYR], [satyr])
AC_ARG_WITH(newt, AS_HELP_STRING([--with-newt],[use newt (default is YES)]), diff --git a/libreport-web.pc.in b/libreport-web.pc.in index ec4ab8e..288e613 100644 --- a/libreport-web.pc.in +++ b/libreport-web.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libreport Description: Library providing network API for libreport Version: @VERSION@ -Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json @SATYR_PKG@ libreport +Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json satyr libreport Libs: -L${libdir} -lreport-web Cflags:
diff --git a/src/lib/json.c b/src/lib/json.c index d5c6f2d..68348ad 100644 --- a/src/lib/json.c +++ b/src/lib/json.c @@ -19,6 +19,9 @@
#include <json/json.h>
+#include <satyr/abrt.h> +#include <satyr/report.h>
#include "internal_libreport.h" #include "ureport.h" #include "libreport_curl.h" @@ -34,11 +37,6 @@ static void ureport_add_str(struct json_object *ur, const char *key, json_object_object_add(ur, key, jstring); }
-#if USE_SATYR
-#include <satyr/abrt.h> -#include <satyr/report.h>
char *ureport_from_dump_dir(const char *dump_dir_path) { char *error_message; @@ -54,286 +52,6 @@ char *ureport_from_dump_dir(const char *dump_dir_path) return json_ureport; }
-#else /* USE_SATYR */
-#include <btparser/thread.h> -#include <btparser/core-backtrace.h>
-/* on success 1 returned, on error zero is returned and appropriate value
- is returned as third argument. You should never read third argument when
- function fails
- json-c library doesn't have any json_object_new_long,
- thus we have to use only int
- */
-static int get_pd_int_item(problem_data_t *pd, const char *key, int *result) -{
- if (!pd || !key)
return 0;
- char *pd_item = problem_data_get_content_or_NULL(pd, key);
- if (!pd_item)
- {
VERB1 log("warning: '%s' is not an item in problem directory", key);
return 0;
- }
- errno = 0;
- char *e;
- long i = strtol(pd_item, &e, 10);
- if (errno || pd_item == e || *e != '\0' || (int) i != i)
return 0;
- *result = i;
- return 1;
-}
-static void ureport_add_int(struct json_object *ur, const char *key, int i) -{
- struct json_object *jint = json_object_new_int(i);
- if (!jint)
die_out_of_memory();
- json_object_object_add(ur, key, jint);
-}
-static void ureport_add_os(struct json_object *ur, problem_data_t *pd) -{
- char *name;
- char *version;
- map_string_t *osinfo = new_map_string();
- problem_data_get_osinfo(pd, osinfo);
- parse_osinfo_for_rhts(osinfo, &name, &version);
- free_map_string(osinfo);
- if (!name || !version)
- {
free(name);
free(version);
return;
- }
- struct json_object *jobject = json_object_new_object();
- if (!jobject)
die_out_of_memory();
- ureport_add_str(jobject, "name", name);
- ureport_add_str(jobject, "version", version);
- free(name);
- free(version);
- json_object_object_add(ur, "os", jobject);
-}
-static bool ureport_add_type(struct json_object *ur, problem_data_t *pd) -{
- char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER);
- if (!pd_item)
- {
error_msg(_("Missing problem element '%s'"), FILENAME_ANALYZER);
return false;
- }
- if (strcmp(pd_item, "CCpp") == 0)
ureport_add_str(ur, "type", "USERSPACE");
- else if (strcmp(pd_item, "Python") == 0)
ureport_add_str(ur, "type", "PYTHON");
- else if (strcmp(pd_item, "Kerneloops") == 0 || strcmp(pd_item, "vmcore") == 0)
ureport_add_str(ur, "type", "KERNELOOPS");
- else
- {
error_msg(_("An unsupported value '%s' in problem element '%s'"), pd_item, FILENAME_ANALYZER);
return false;
- }
- return true;
-}
-static void ureport_add_core_backtrace(struct json_object *ur, problem_data_t *pd) -{
- char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_CORE_BACKTRACE);
- if (!pd_item)
return;
- struct btp_thread *core_bt = btp_load_core_backtrace(pd_item);
- if (!core_bt)
return;
- struct json_object *jarray = json_object_new_array();
- if (!jarray)
die_out_of_memory();
- struct btp_frame *frame;
- unsigned frame_nr = 0;
- for (frame = core_bt->frames; frame; frame = frame->next)
- {
struct frame_aux *aux = frame->user_data;
struct json_object *item = json_object_new_object();
if (!item)
die_out_of_memory();
if (aux->filename)
ureport_add_str(item, "path", aux->filename);
if (frame->function_name)
ureport_add_str(item, "funcname", frame->function_name);
if (aux->build_id)
ureport_add_str(item, "buildid", aux->build_id);
if (aux->fingerprint)
ureport_add_str(item, "funchash", aux->fingerprint);
/* always add offset - even offset 0 is valid */
ureport_add_int(item, "offset", (uintmax_t)frame->address);
ureport_add_int(item, "frame", frame_nr++);
ureport_add_int(item, "thread", 0);
json_object_array_add(jarray, item);
- }
- btp_thread_free(core_bt);
- json_object_object_add(ur, FILENAME_CORE_BACKTRACE, jarray);
-} -static void ureport_add_item_str(struct json_object *ur, problem_data_t *pd,
const char *key, const char *rename)
-{
char *pd_item = problem_data_get_content_or_NULL(pd, key);
if (!pd_item)
return;
ureport_add_str(ur, (rename) ?: key, pd_item);
-}
-static void ureport_add_item_int(struct json_object *ur, problem_data_t *pd,
const char *key, const char *rename)
-{
- int nr;
- int stat = get_pd_int_item(pd, key, &nr);
- if (!stat)
return;
- ureport_add_int(ur, (rename) ?: key, nr);
-}
-static void ureport_add_pkg(struct json_object *ur, problem_data_t *pd) -{
- struct json_object *jobject = json_object_new_object();
- if (!jobject)
die_out_of_memory();
- ureport_add_item_int(jobject, pd, FILENAME_PKG_EPOCH, "epoch");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_NAME, "name");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_VERSION, "version");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_RELEASE, "release");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_ARCH, "architecture");
- json_object_object_add(ur, "installed_package", jobject);
-}
-static void ureport_add_related_pkgs(struct json_object *ur, problem_data_t *pd) -{
- // TODO: populate this field
- struct json_object *jobject = json_object_new_array();
- json_object_object_add(ur, "related_packages", jobject);
-}
-static void ureport_add_reporter(struct json_object *ur, const char *name, const char *version) -{
- struct json_object *jobject = json_object_new_object();
- if (!jobject)
die_out_of_memory();
- ureport_add_str(jobject, "name", name);
- ureport_add_str(jobject, "version", version);
- json_object_object_add(ur, "reporter", jobject);
-}
-static void ureport_add_oops(struct json_object *ur, problem_data_t *pd) -{
- char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER);
- if (!pd_item)
return;
- if (!strcmp(pd_item, "Kerneloops"))
ureport_add_item_str(ur, pd, FILENAME_BACKTRACE, "oops");
-}
-char *new_json_ureport(problem_data_t *pd) -{
- struct json_object *ureport = json_object_new_object();
- if (!ureport)
die_out_of_memory();
- ureport_add_item_str(ureport, pd, "user_type", NULL);
- ureport_add_item_int(ureport, pd, "uptime", NULL);
- /* mandatory, but not in problem-dir
- ureport_add_item_int(ureport, pd, "crash_thread", NULL);
- */
- ureport_add_int(ureport, "ureport_version", 1);
- ureport_add_int(ureport, "crash_thread", 0);
- ureport_add_item_str(ureport, pd, FILENAME_ARCHITECTURE, NULL);
- ureport_add_item_str(ureport, pd, FILENAME_EXECUTABLE, NULL);
- ureport_add_item_str(ureport, pd, FILENAME_REASON, NULL);
- ureport_add_item_str(ureport, pd, FILENAME_COMPONENT, NULL);
- if (!ureport_add_type(ureport, pd))
- {
error_msg(_("Can't create an uReport without 'type'"));
json_object_put(ureport);
return NULL;
- }
- ureport_add_pkg(ureport, pd);
- ureport_add_related_pkgs(ureport, pd);
- ureport_add_os(ureport, pd);
- ureport_add_core_backtrace(ureport, pd);
- ureport_add_reporter(ureport, "ABRT", VERSION);
- ureport_add_oops(ureport, pd);
- char *j = xstrdup(json_object_to_json_string(ureport));
- json_object_put(ureport);
- return j;
-}
-char *ureport_from_dump_dir(const char *dump_dir_path) -{
- struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY);
- if (!dd)
xfunc_die();
- problem_data_t *pd = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
- if (!pd)
xfunc_die(); /* create_problem_data_from_dump_dir already emitted error msg */
- char *json_ureport = new_json_ureport(pd);
- problem_data_free(pd);
- if (json_ureport == NULL)
- {
error_msg(_("Not uploading an empty uReport"));
return NULL;
- }
- return json_ureport;
-}
-#endif /* USE_SATYR */
char *new_json_attachment(const char *bthash, const char *type, const char *data) { struct json_object *attachment = json_object_new_object(); diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c index 626b41f..972a1f0 100644 --- a/src/plugins/reporter-bugzilla.c +++ b/src/plugins/reporter-bugzilla.c @@ -21,39 +21,8 @@ #include "abrt_xmlrpc.h" #include "rhbz.h"
-/* btparser compatibility - once we move to satyr, the else branch of the ifdef
- can be removed
- */
-#ifdef USE_SATYR
-#include <satyr/location.h> -#include <satyr/gdb_stacktrace.h> -#include <satyr/gdb_thread.h> -#include <satyr/gdb_frame.h> -#include <satyr/strbuf.h>
-#else /* USE_SATYR */
-#include <btparser/location.h> -#include <btparser/backtrace.h> -#include <btparser/thread.h> -#include <btparser/frame.h> -#include <btparser/strbuf.h>
-#define sr_location btp_location -#define sr_location_init btp_location_init -#define sr_gdb_stacktrace btp_backtrace -#define sr_gdb_stacktrace_parse btp_backtrace_parse -#define sr_gdb_stacktrace_get_optimized_thread btp_backtrace_get_optimized_thread -#define sr_gdb_stacktrace_free btp_backtrace_free -#define sr_gdb_thread btp_thread -#define sr_gdb_thread_append_to_str btp_thread_append_to_str -#define sr_gdb_thread_free btp_thread_free -#define sr_strbuf btp_strbuf -#define sr_strbuf_new btp_strbuf_new -#define sr_strbuf_free_nobuf btp_strbuf_free_nobuf
-#endif /* USE_SATYR */ +#include <satyr/stacktrace.h> +#include <satyr/abrt.h>
struct section_t { char *name; @@ -365,38 +334,38 @@ int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data,
if (strlen(item->content) >= max_text_size) {
struct sr_location location;
sr_location_init(&location);
char *error_msg = NULL;
const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
if (!analyzer)
return 0;
/* For CCpp crashes, use the GDB-produced backtrace which should be
* available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE
* by default for CCpp crashes.
*/
enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer);
if (strcmp(analyzer, "CCpp") == 0)
report_type = SR_REPORT_GDB;
/* sr_gdb_stacktrace_parse modifies the input parameter */
char *content = item->content;
struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location);
struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type,
item->content, &error_msg); if (!backtrace) {
log(_("Can't parse backtrace"));
log(_("Can't parse backtrace: %s"), error_msg);
free(error_msg); return 0; } /* Get optimized thread stack trace for 10 top most frames */
struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10);
sr_gdb_stacktrace_free(backtrace);
truncated = sr_stacktrace_to_short_text(backtrace, 10);
sr_stacktrace_free(backtrace);
if (!thread)
if (!truncated) {
log(_("Can't find crash thread"));
log(_("Can't generate stacktrace description (no crash thread?)")); return 0; }
/* Cannot be NULL, it dies on memory error */
struct sr_strbuf *bt = sr_strbuf_new();
sr_gdb_thread_append_to_str(thread, bt, true);
sr_gdb_thread_free(thread);
truncated = sr_strbuf_free_nobuf(bt);
}
append_text(result,
Additional information: reporter-ureport doesn't work together with the currently running FAF instance at https://retrace.fedoraproject.org/faf/ (the default URL) But it isn't problem because it was expected ... :)
Produced error message: Server responded with an error: 'Validation failed: error validating 'os': unknown elements present: [u'architecture']'
On Mon, 2013-07-15 at 16:17 +0200, Jakub Filak wrote:
Reporting works fine with these patches (except reporter-ureport). Pushed both. Thank you!
On Tue, 2013-07-09 at 18:26 +0200, Martin Milata wrote:
Related to abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com
configure.ac | 18 +-- libreport-web.pc.in | 2 +- src/lib/json.c | 288 +--------------------------------------- src/plugins/reporter-bugzilla.c | 75 +++-------- 4 files changed, 27 insertions(+), 356 deletions(-)
diff --git a/configure.ac b/configure.ac index 671d6a4..da7f480 100644 --- a/configure.ac +++ b/configure.ac @@ -145,11 +145,6 @@ 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([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) @@ -158,18 +153,7 @@ PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([PROXY], [libproxy-1.0], [ AC_DEFINE([HAVE_PROXY], [1], [Use libproxy]) ], [:])
-[if test "$with_satyr" = "yes"] -[then]
- PKG_CHECK_MODULES([SATYR], [satyr])
- AC_DEFINE([USE_SATYR], [1], [Use satyr instead of btparser])
- SATYR_PKG="satyr"
-[else]
- PKG_CHECK_MODULES([SATYR], [btparser])
- SATYR_PKG="btparser"
-[fi] -AC_SUBST(SATYR_PKG) -AM_CONDITIONAL([USE_SATYR], [test "$with_satyr" = "yes"]) +PKG_CHECK_MODULES([SATYR], [satyr])
AC_ARG_WITH(newt, AS_HELP_STRING([--with-newt],[use newt (default is YES)]), diff --git a/libreport-web.pc.in b/libreport-web.pc.in index ec4ab8e..288e613 100644 --- a/libreport-web.pc.in +++ b/libreport-web.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libreport Description: Library providing network API for libreport Version: @VERSION@ -Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json @SATYR_PKG@ libreport +Requires: glib-2.0 libcurl libproxy-1.0 libxml-2.0 xmlrpc xmlrpc_client json satyr libreport Libs: -L${libdir} -lreport-web Cflags:
diff --git a/src/lib/json.c b/src/lib/json.c index d5c6f2d..68348ad 100644 --- a/src/lib/json.c +++ b/src/lib/json.c @@ -19,6 +19,9 @@
#include <json/json.h>
+#include <satyr/abrt.h> +#include <satyr/report.h>
#include "internal_libreport.h" #include "ureport.h" #include "libreport_curl.h" @@ -34,11 +37,6 @@ static void ureport_add_str(struct json_object *ur, const char *key, json_object_object_add(ur, key, jstring); }
-#if USE_SATYR
-#include <satyr/abrt.h> -#include <satyr/report.h>
char *ureport_from_dump_dir(const char *dump_dir_path) { char *error_message; @@ -54,286 +52,6 @@ char *ureport_from_dump_dir(const char *dump_dir_path) return json_ureport; }
-#else /* USE_SATYR */
-#include <btparser/thread.h> -#include <btparser/core-backtrace.h>
-/* on success 1 returned, on error zero is returned and appropriate value
- is returned as third argument. You should never read third argument when
- function fails
- json-c library doesn't have any json_object_new_long,
- thus we have to use only int
- */
-static int get_pd_int_item(problem_data_t *pd, const char *key, int *result) -{
- if (!pd || !key)
return 0;
- char *pd_item = problem_data_get_content_or_NULL(pd, key);
- if (!pd_item)
- {
VERB1 log("warning: '%s' is not an item in problem directory", key);
return 0;
- }
- errno = 0;
- char *e;
- long i = strtol(pd_item, &e, 10);
- if (errno || pd_item == e || *e != '\0' || (int) i != i)
return 0;
- *result = i;
- return 1;
-}
-static void ureport_add_int(struct json_object *ur, const char *key, int i) -{
- struct json_object *jint = json_object_new_int(i);
- if (!jint)
die_out_of_memory();
- json_object_object_add(ur, key, jint);
-}
-static void ureport_add_os(struct json_object *ur, problem_data_t *pd) -{
- char *name;
- char *version;
- map_string_t *osinfo = new_map_string();
- problem_data_get_osinfo(pd, osinfo);
- parse_osinfo_for_rhts(osinfo, &name, &version);
- free_map_string(osinfo);
- if (!name || !version)
- {
free(name);
free(version);
return;
- }
- struct json_object *jobject = json_object_new_object();
- if (!jobject)
die_out_of_memory();
- ureport_add_str(jobject, "name", name);
- ureport_add_str(jobject, "version", version);
- free(name);
- free(version);
- json_object_object_add(ur, "os", jobject);
-}
-static bool ureport_add_type(struct json_object *ur, problem_data_t *pd) -{
- char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER);
- if (!pd_item)
- {
error_msg(_("Missing problem element '%s'"), FILENAME_ANALYZER);
return false;
- }
- if (strcmp(pd_item, "CCpp") == 0)
ureport_add_str(ur, "type", "USERSPACE");
- else if (strcmp(pd_item, "Python") == 0)
ureport_add_str(ur, "type", "PYTHON");
- else if (strcmp(pd_item, "Kerneloops") == 0 || strcmp(pd_item, "vmcore") == 0)
ureport_add_str(ur, "type", "KERNELOOPS");
- else
- {
error_msg(_("An unsupported value '%s' in problem element '%s'"), pd_item, FILENAME_ANALYZER);
return false;
- }
- return true;
-}
-static void ureport_add_core_backtrace(struct json_object *ur, problem_data_t *pd) -{
- char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_CORE_BACKTRACE);
- if (!pd_item)
return;
- struct btp_thread *core_bt = btp_load_core_backtrace(pd_item);
- if (!core_bt)
return;
- struct json_object *jarray = json_object_new_array();
- if (!jarray)
die_out_of_memory();
- struct btp_frame *frame;
- unsigned frame_nr = 0;
- for (frame = core_bt->frames; frame; frame = frame->next)
- {
struct frame_aux *aux = frame->user_data;
struct json_object *item = json_object_new_object();
if (!item)
die_out_of_memory();
if (aux->filename)
ureport_add_str(item, "path", aux->filename);
if (frame->function_name)
ureport_add_str(item, "funcname", frame->function_name);
if (aux->build_id)
ureport_add_str(item, "buildid", aux->build_id);
if (aux->fingerprint)
ureport_add_str(item, "funchash", aux->fingerprint);
/* always add offset - even offset 0 is valid */
ureport_add_int(item, "offset", (uintmax_t)frame->address);
ureport_add_int(item, "frame", frame_nr++);
ureport_add_int(item, "thread", 0);
json_object_array_add(jarray, item);
- }
- btp_thread_free(core_bt);
- json_object_object_add(ur, FILENAME_CORE_BACKTRACE, jarray);
-} -static void ureport_add_item_str(struct json_object *ur, problem_data_t *pd,
const char *key, const char *rename)
-{
char *pd_item = problem_data_get_content_or_NULL(pd, key);
if (!pd_item)
return;
ureport_add_str(ur, (rename) ?: key, pd_item);
-}
-static void ureport_add_item_int(struct json_object *ur, problem_data_t *pd,
const char *key, const char *rename)
-{
- int nr;
- int stat = get_pd_int_item(pd, key, &nr);
- if (!stat)
return;
- ureport_add_int(ur, (rename) ?: key, nr);
-}
-static void ureport_add_pkg(struct json_object *ur, problem_data_t *pd) -{
- struct json_object *jobject = json_object_new_object();
- if (!jobject)
die_out_of_memory();
- ureport_add_item_int(jobject, pd, FILENAME_PKG_EPOCH, "epoch");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_NAME, "name");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_VERSION, "version");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_RELEASE, "release");
- ureport_add_item_str(jobject, pd, FILENAME_PKG_ARCH, "architecture");
- json_object_object_add(ur, "installed_package", jobject);
-}
-static void ureport_add_related_pkgs(struct json_object *ur, problem_data_t *pd) -{
- // TODO: populate this field
- struct json_object *jobject = json_object_new_array();
- json_object_object_add(ur, "related_packages", jobject);
-}
-static void ureport_add_reporter(struct json_object *ur, const char *name, const char *version) -{
- struct json_object *jobject = json_object_new_object();
- if (!jobject)
die_out_of_memory();
- ureport_add_str(jobject, "name", name);
- ureport_add_str(jobject, "version", version);
- json_object_object_add(ur, "reporter", jobject);
-}
-static void ureport_add_oops(struct json_object *ur, problem_data_t *pd) -{
- char *pd_item = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER);
- if (!pd_item)
return;
- if (!strcmp(pd_item, "Kerneloops"))
ureport_add_item_str(ur, pd, FILENAME_BACKTRACE, "oops");
-}
-char *new_json_ureport(problem_data_t *pd) -{
- struct json_object *ureport = json_object_new_object();
- if (!ureport)
die_out_of_memory();
- ureport_add_item_str(ureport, pd, "user_type", NULL);
- ureport_add_item_int(ureport, pd, "uptime", NULL);
- /* mandatory, but not in problem-dir
- ureport_add_item_int(ureport, pd, "crash_thread", NULL);
- */
- ureport_add_int(ureport, "ureport_version", 1);
- ureport_add_int(ureport, "crash_thread", 0);
- ureport_add_item_str(ureport, pd, FILENAME_ARCHITECTURE, NULL);
- ureport_add_item_str(ureport, pd, FILENAME_EXECUTABLE, NULL);
- ureport_add_item_str(ureport, pd, FILENAME_REASON, NULL);
- ureport_add_item_str(ureport, pd, FILENAME_COMPONENT, NULL);
- if (!ureport_add_type(ureport, pd))
- {
error_msg(_("Can't create an uReport without 'type'"));
json_object_put(ureport);
return NULL;
- }
- ureport_add_pkg(ureport, pd);
- ureport_add_related_pkgs(ureport, pd);
- ureport_add_os(ureport, pd);
- ureport_add_core_backtrace(ureport, pd);
- ureport_add_reporter(ureport, "ABRT", VERSION);
- ureport_add_oops(ureport, pd);
- char *j = xstrdup(json_object_to_json_string(ureport));
- json_object_put(ureport);
- return j;
-}
-char *ureport_from_dump_dir(const char *dump_dir_path) -{
- struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY);
- if (!dd)
xfunc_die();
- problem_data_t *pd = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
- if (!pd)
xfunc_die(); /* create_problem_data_from_dump_dir already emitted error msg */
- char *json_ureport = new_json_ureport(pd);
- problem_data_free(pd);
- if (json_ureport == NULL)
- {
error_msg(_("Not uploading an empty uReport"));
return NULL;
- }
- return json_ureport;
-}
-#endif /* USE_SATYR */
char *new_json_attachment(const char *bthash, const char *type, const char *data) { struct json_object *attachment = json_object_new_object(); diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c index 626b41f..972a1f0 100644 --- a/src/plugins/reporter-bugzilla.c +++ b/src/plugins/reporter-bugzilla.c @@ -21,39 +21,8 @@ #include "abrt_xmlrpc.h" #include "rhbz.h"
-/* btparser compatibility - once we move to satyr, the else branch of the ifdef
- can be removed
- */
-#ifdef USE_SATYR
-#include <satyr/location.h> -#include <satyr/gdb_stacktrace.h> -#include <satyr/gdb_thread.h> -#include <satyr/gdb_frame.h> -#include <satyr/strbuf.h>
-#else /* USE_SATYR */
-#include <btparser/location.h> -#include <btparser/backtrace.h> -#include <btparser/thread.h> -#include <btparser/frame.h> -#include <btparser/strbuf.h>
-#define sr_location btp_location -#define sr_location_init btp_location_init -#define sr_gdb_stacktrace btp_backtrace -#define sr_gdb_stacktrace_parse btp_backtrace_parse -#define sr_gdb_stacktrace_get_optimized_thread btp_backtrace_get_optimized_thread -#define sr_gdb_stacktrace_free btp_backtrace_free -#define sr_gdb_thread btp_thread -#define sr_gdb_thread_append_to_str btp_thread_append_to_str -#define sr_gdb_thread_free btp_thread_free -#define sr_strbuf btp_strbuf -#define sr_strbuf_new btp_strbuf_new -#define sr_strbuf_free_nobuf btp_strbuf_free_nobuf
-#endif /* USE_SATYR */ +#include <satyr/stacktrace.h> +#include <satyr/abrt.h>
struct section_t { char *name; @@ -365,38 +334,38 @@ int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data,
if (strlen(item->content) >= max_text_size) {
struct sr_location location;
sr_location_init(&location);
char *error_msg = NULL;
const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
if (!analyzer)
return 0;
/* For CCpp crashes, use the GDB-produced backtrace which should be
* available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE
* by default for CCpp crashes.
*/
enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer);
if (strcmp(analyzer, "CCpp") == 0)
report_type = SR_REPORT_GDB;
/* sr_gdb_stacktrace_parse modifies the input parameter */
char *content = item->content;
struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location);
struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type,
item->content, &error_msg); if (!backtrace) {
log(_("Can't parse backtrace"));
log(_("Can't parse backtrace: %s"), error_msg);
free(error_msg); return 0; } /* Get optimized thread stack trace for 10 top most frames */
struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10);
sr_gdb_stacktrace_free(backtrace);
truncated = sr_stacktrace_to_short_text(backtrace, 10);
sr_stacktrace_free(backtrace);
if (!thread)
if (!truncated) {
log(_("Can't find crash thread"));
log(_("Can't generate stacktrace description (no crash thread?)")); return 0; }
/* Cannot be NULL, it dies on memory error */
struct sr_strbuf *bt = sr_strbuf_new();
sr_gdb_thread_append_to_str(thread, bt, true);
sr_gdb_thread_free(thread);
truncated = sr_strbuf_free_nobuf(bt);
}
append_text(result,
Closes abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com --- configure.ac | 14 +- doc/abrt-action-generate-core-backtrace.txt | 50 +----- src/daemon/abrt-handle-event.c | 81 +++++----- src/include/Makefile.am | 1 - src/include/satyr-compat.h | 171 -------------------- src/plugins/abrt-action-analyze-backtrace.c | 41 +++-- src/plugins/abrt-action-generate-core-backtrace.c | 180 ++-------------------- src/plugins/koops_event.conf | 1 - src/plugins/python_event.conf | 1 - src/plugins/vmcore_event.conf | 1 - 10 files changed, 92 insertions(+), 449 deletions(-) delete mode 100644 src/include/satyr-compat.h
diff --git a/configure.ac b/configure.ac index ccd3901..7b32618 100644 --- a/configure.ac +++ b/configure.ac @@ -92,11 +92,6 @@ 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]) @@ -109,14 +104,7 @@ 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_CHECK_MODULES([SATYR], [satyr])
PKG_PROG_PKG_CONFIG AC_ARG_WITH([systemdsystemunitdir], diff --git a/doc/abrt-action-generate-core-backtrace.txt b/doc/abrt-action-generate-core-backtrace.txt index 0e68031..988327f 100644 --- a/doc/abrt-action-generate-core-backtrace.txt +++ b/doc/abrt-action-generate-core-backtrace.txt @@ -3,12 +3,11 @@ abrt-action-generate-core-backtrace(1)
NAME ---- -abrt-action-generate-core-backtrace - Generates coredump-level (debuginfo-free) -backtrace +abrt-action-generate-core-backtrace - Generates coredump-level backtrace
SYNOPSIS -------- -'abrt-action-generate-core-backtrace' [-v] [-d DIR] +'abrt-action-generate-core-backtrace' [-v] [-r] [-d DIR]
DESCRIPTION ----------- @@ -22,8 +21,7 @@ However, it only contains information that can be obtained from the coredump without debugging symbols available - mainly relative addresses of the stored instruction pointers. Such backtrace can still be useful for reporting and reproducing the bug and does not require debugging -information files to be installed. See <<X1,*FILE FORMAT*>> for the -description of the generated file. +information files to be installed.
The result is saved in the problem directory in a file named 'core_backtrace'. @@ -45,48 +43,12 @@ OPTIONS -d DIR:: Path to problem directory.
+-r:: + Do not hash function fingerprints. Useful for debugging. + -v:: Be more verbose. Can be given multiple times.
-[[X1]] -FILE FORMAT ------------ - -The generated file is a text file containing one line for each stack frame of -the thread that most likely caused the crash. The line has following format: - ------------- -BUILD_ID OFFSET SYMBOL MODNAME FINGERPRINT ------------- - -Where: - -*BUILD_ID*:: - Build ID of the binary file the address is mapped to as a hexadecimal string. - -*OFFSET*:: - Offset from the start of the executable section of aforementioned file the - stored instruction pointer points to. Number in hexadecimal format. - -*SYMBOL*:: - Name of the function if it is present in the binary (which is often the case - for shared libraries). - -*MODNAME*:: - Name of the module. Contains name of a library or *[exe]* if it is the - executable. - -*FINGERPRINT*:: - Fingerprint of the function the instruction pointer points to (x86-64 only). - The fingerprint is generated from various aspects of the machine code of the - function in question. Its purpose is to supplant the BUILD_ID and OFFSET - pair in case they are not present and to allow for comparison of - coredump-level backtraces produced by two slightly different versions of a - program. - -Dash in place of any of the parts indicates that the part is unknown. - -
AUTHORS ------- diff --git a/src/daemon/abrt-handle-event.c b/src/daemon/abrt-handle-event.c index a426566..eadb058 100644 --- a/src/daemon/abrt-handle-event.c +++ b/src/daemon/abrt-handle-event.c @@ -16,22 +16,42 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <satyr/thread.h> +#include <satyr/stacktrace.h> +#include <satyr/distance.h> +#include <satyr/abrt.h>
#include "libabrt.h" #include <libreport/run_event.h> -#include "satyr-compat.h" + +/* 70 % similarity */ +#define BACKTRACE_DUP_THRESHOLD 0.3
static char *uid = NULL; static char *uuid = NULL; -static struct sr_core_stacktrace *corebt = NULL; +static struct sr_stacktrace *corebt = NULL; +static char *analyzer = NULL; static char *crash_dump_dup_name = NULL;
-static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, +static char* load_backtrace(const struct dump_dir *dd) +{ + const char *filename = FILENAME_BACKTRACE; + if (strcmp(analyzer, "CCpp") == 0) + { + filename = FILENAME_CORE_BACKTRACE; + } + + return dd_load_text_ext(dd, filename, + DD_FAIL_QUIETLY_ENOENT|DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); +} + +static int core_backtrace_is_duplicate(struct sr_stacktrace *bt1, const char *bt2_text) { int result; char *error_message; - struct sr_core_stacktrace *bt2 = sr_core_stacktrace_from_json_text(bt2_text, &error_message); + struct sr_stacktrace *bt2 = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer), + bt2_text, &error_message); if (bt2 == NULL) { VERB1 log("Failed to parse backtrace, considering it not duplicate: %s", error_message); @@ -39,10 +59,10 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, return 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); + struct sr_thread *thread1 = sr_stacktrace_find_crash_thread(bt1); + struct sr_thread *thread2 = sr_stacktrace_find_crash_thread(bt2);
- int length2 = sr_core_thread_get_frame_count(thread2); + int length2 = sr_thread_frame_count(thread2);
if (length2 <= 0) { @@ -52,7 +72,7 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, }
/* This is an ugly workaround for https://github.com/abrt/btparser/issues/6 */ -#ifndef USE_SATYR + /* int length1 = sr_core_thread_get_frame_count(thread1);
if (length1 <= 2 || length2 <= 2) @@ -61,23 +81,14 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, result = (sr_core_thread_cmp(thread1, thread2) == 0); goto end; } -#endif - - float distance = sr_distance_core(SR_DISTANCE_DAMERAU_LEVENSHTEIN, - thread1, thread2); + */
- if (distance == -1) - { - result = 0; - } - else - { - VERB2 log("Distance between backtraces: %f", distance); - result = (distance <= BACKTRACE_DUP_THRESHOLD); - } + float distance = sr_distance(SR_DISTANCE_DAMERAU_LEVENSHTEIN, thread1, thread2); + VERB2 log("Distance between backtraces: %f", distance); + result = (distance <= BACKTRACE_DUP_THRESHOLD);
end: - sr_core_stacktrace_free(bt2); + sr_stacktrace_free(bt2);
return result; } @@ -126,22 +137,17 @@ static void dup_uuid_fini(void)
static void dup_corebt_init(const struct dump_dir *dd) { - char *corebt_text; - if (corebt) return; /* already checked */
- corebt_text = dd_load_text_ext(dd, FILENAME_CORE_BACKTRACE, - DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE - ); - + char *corebt_text = load_backtrace(dd); if (!corebt_text) return; /* no backtrace */
+ /* sr_stacktrace_parse moves the pointer */ char *error_message; - corebt = sr_core_stacktrace_from_json_text(corebt_text, - &error_message); - + corebt = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer), + corebt_text, &error_message); if (!corebt) { VERB1 log("Failed to load core stacktrace: %s", error_message); @@ -157,9 +163,8 @@ static int dup_corebt_compare(const struct dump_dir *dd) return 0;
int isdup; - char *dd_corebt = dd_load_text_ext(dd, FILENAME_CORE_BACKTRACE, - DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
+ char *dd_corebt = load_backtrace(dd); if (!dd_corebt) return 0;
@@ -174,7 +179,7 @@ static int dup_corebt_compare(const struct dump_dir *dd)
static void dup_corebt_fini(void) { - sr_core_stacktrace_free(corebt); + sr_stacktrace_free(corebt); corebt = NULL; }
@@ -208,13 +213,13 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param) if (!dd) return 0; /* wtf? (error, but will be handled elsewhere later) */
- dup_uuid_init(dd); - dup_corebt_init(dd); - - char *analyzer = dd_load_text(dd, FILENAME_ANALYZER); + analyzer = dd_load_text(dd, FILENAME_ANALYZER); /* dump_dir_name can be relative */ dump_dir_name = realpath(dump_dir_name, NULL);
+ dup_uuid_init(dd); + dup_corebt_init(dd); + dd_close(dd);
DIR *dir = opendir(g_settings_dump_location); diff --git a/src/include/Makefile.am b/src/include/Makefile.am index addbaa5..49a6f5c 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -5,5 +5,4 @@ libabrt_include_HEADERS = \ libabrt.h \ abrt-dbus.h \ hooklib.h \ - satyr-compat.h \ problem_api.h diff --git a/src/include/satyr-compat.h b/src/include/satyr-compat.h deleted file mode 100644 index 23f6bb7..0000000 --- a/src/include/satyr-compat.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - 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.0 - -/* abrt-handle-event.c */ -#define sr_core_stacktrace btp_thread -#define sr_core_thread btp_thread - -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); -} - -int -sr_core_thread_cmp(struct sr_core_thread *thread1, - struct sr_core_thread *thread2) -{ - return btp_thread_cmp(thread1, thread2); -} - -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/abrt-action-analyze-backtrace.c b/src/plugins/abrt-action-analyze-backtrace.c index a980213..9348195 100644 --- a/src/plugins/abrt-action-analyze-backtrace.c +++ b/src/plugins/abrt-action-analyze-backtrace.c @@ -15,7 +15,11 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "satyr-compat.h" +#include <satyr/location.h> +#include <satyr/thread.h> +#include <satyr/gdb/frame.h> +#include <satyr/gdb/stacktrace.h> + #include "libabrt.h"
static const char *dump_dir_name = "."; @@ -130,18 +134,29 @@ int main(int argc, char **argv) }
/* Compute duplication hash. */ - 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); - - VERB3 log("Generating duphash: %s", str_hash->buf); - char hash_str[SHA1_RESULT_LEN*2 + 1]; - create_hash(hash_str, str_hash->buf); - - dd_save_text(dd, FILENAME_DUPHASH, hash_str); - strbuf_free(str_hash); - free(str_hash_core); + struct sr_thread *crash_thread = + (struct sr_thread *)sr_gdb_stacktrace_find_crash_thread(backtrace); + + if (crash_thread) + { + char *hash_str; + + if (g_verbose >= 3) + { + hash_str = sr_thread_get_duphash(crash_thread, 3, component, + SR_DUPHASH_NOHASH); + log("Generating duphash: %s", hash_str); + free(hash_str); + } + + hash_str = sr_thread_get_duphash(crash_thread, 3, component, + SR_DUPHASH_NORMAL); + dd_save_text(dd, FILENAME_DUPHASH, hash_str); + free(hash_str); + } + else + log(_("Crash thread not found")); +
/* Compute the backtrace rating. */ float quality = sr_gdb_stacktrace_quality_complex(backtrace); diff --git a/src/plugins/abrt-action-generate-core-backtrace.c b/src/plugins/abrt-action-generate-core-backtrace.c index 24d69cb..a549a53 100644 --- a/src/plugins/abrt-action-generate-core-backtrace.c +++ b/src/plugins/abrt-action-generate-core-backtrace.c @@ -16,74 +16,10 @@ with this program; if not, write to the Free Software Foundation, Inc., 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 <satyr/abrt.h> +#include <satyr/utils.h>
-#include <btparser/hash_sha1.h> -#include <btparser/utils.h> -#include <btparser/core-backtrace.h> -#include <btparser/core-backtrace-python.h> -#include <btparser/core-backtrace-oops.h> - -static bool raw_fingerprints = false; - -/* add the information about '?' flag to fingerprint field - fingerprint is otherwise always empty for kerneloops */ -static void oops_add_question_marks(GList *backtrace) -{ - GList *elem = backtrace; - struct backtrace_entry *entry; - while (elem) - { - entry = (struct backtrace_entry *)elem->data; - if (entry->function_initial_loc) - entry->fingerprint = btp_strdup("?"); - - elem = g_list_next(elem); - } -} - -static void hash_fingerprints(GList *backtrace) -{ - GList *elem = backtrace; - struct backtrace_entry *entry; - char bin_hash[BTP_SHA1_RESULT_BIN_LEN], hash[BTP_SHA1_RESULT_LEN]; - btp_sha1_ctx_t ctx; - while (elem) - { - entry = (struct backtrace_entry *)elem->data; - if (entry->fingerprint) - { - btp_sha1_begin(&ctx); - btp_sha1_hash(&ctx, entry->fingerprint, strlen(entry->fingerprint)); - btp_sha1_end(&ctx, bin_hash); - btp_bin2hex(hash, bin_hash, sizeof(bin_hash))[0] = '\0'; - - free(entry->fingerprint); - entry->fingerprint = btp_strndup(hash, sizeof(hash)); - } - elem = g_list_next(elem); - } -} +#include "libabrt.h"
int main(int argc, char **argv) { @@ -97,12 +33,11 @@ int main(int argc, char **argv) abrt_init(argv);
const char *dump_dir_name = "."; - /* 60 seconds was too limiting on slow machines */ - const int exec_timeout_sec = 240; + bool raw_fingerprints = false;
/* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( - "& [-v] -d DIR\n" + "& [-v] [-r] -d DIR\n" "\n" "Creates coredump-level backtrace from core dump and corresponding binary" ); @@ -123,109 +58,22 @@ int main(int argc, char **argv) export_abrt_envvars(0);
if (g_verbose > 1) - btp_debug_parser = true; + sr_debug_parser = true;
/* Let user know what's going on */ log(_("Generating core_backtrace"));
- /* Get the executable name -- unstrip doesn't know it. */ - struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY); - if (!dd) - xfunc_die(); /* dd_opendir already printed error msg */ - char *analyzer = dd_load_text(dd, FILENAME_ANALYZER); - char *executable = dd_load_text_ext(dd, FILENAME_EXECUTABLE, - DD_FAIL_QUIETLY_ENOENT); - char *txt_backtrace = dd_load_text_ext(dd, FILENAME_BACKTRACE, - DD_FAIL_QUIETLY_ENOENT); - char *kernel = dd_load_text_ext(dd, FILENAME_KERNEL, - DD_FAIL_QUIETLY_ENOENT | - DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); - dd_close(dd); - - /* Parse addresses and eventual symbols from the output */ - GList *backtrace; - if (strcmp(analyzer, "CCpp") == 0) - { - char *gdb_out = get_backtrace(dump_dir_name, exec_timeout_sec, NULL); - if (gdb_out == NULL) - xfunc_die(); - - /* We observed a case when we were stuck for 36 minutes after emitting - * "Generating backtrace" message (in get_backtrace). - * We don't know whether we finished bt generation - * and were stuck somewhere below this point, or we were stuck - * in get_backtrace(). For now, we emit this message - * even in non-verbose mode to aid in future debugging: - */ - log(_("Backtrace is generated, %u bytes"), (int)strlen(gdb_out)); - - backtrace = btp_backtrace_extract_addresses(gdb_out); - VERB1 log("Extracted %d frames from the backtrace", g_list_length(backtrace)); - free(gdb_out); + char *error_message = NULL; + bool success = sr_abrt_create_core_stacktrace(dump_dir_name, + !raw_fingerprints, + &error_message);
- VERB1 log("Running eu-unstrip -n to obtain build ids"); - /* Run eu-unstrip -n to obtain the ids. This should be rewritten to read - * them directly from the core. */ - char *unstrip_output = run_unstrip_n(dump_dir_name, /*timeout_sec:*/ 30); - if (unstrip_output == NULL) - error_msg_and_die("Running eu-unstrip failed"); - btp_core_assign_build_ids(backtrace, unstrip_output, executable); - free(unstrip_output); - - /* Remove empty lines from the backtrace. */ - GList *loop = backtrace; - while (loop != NULL) - { - struct backtrace_entry *entry = loop->data; - GList *const tmp_next = g_list_next(loop); - if (!entry->build_id && !entry->filename && !entry->modname) - backtrace = g_list_delete_link(backtrace, loop); - loop = tmp_next; - } - - /* Extract address ranges from all the executables in the backtrace */ - VERB1 log("Computing function fingerprints"); - btp_core_backtrace_fingerprint(backtrace); - if (!raw_fingerprints) - hash_fingerprints(backtrace); - } - else if (strcmp(analyzer, "Python") == 0) - backtrace = btp_parse_python_backtrace(txt_backtrace); - else if (strcmp(analyzer, "Kerneloops") == 0 || strcmp(analyzer, "vmcore") == 0) + if (!success) { - /* btp_parse_kerneloops() accepts NULL in the kernelver argument. It is not - * documented, but it is true. */ - if (kernel != NULL) - { - char *space = strchr(kernel, ' '); - if (space) - *space = '\0'; - } - - backtrace = btp_parse_kerneloops(txt_backtrace, kernel); - oops_add_question_marks(backtrace); + log(_("Error: %s"), error_message); + free(error_message); + return 1; } - else - error_msg_and_die(_("Core-backtraces are not supported for '%s'"), analyzer); - - free(txt_backtrace); - free(kernel); - free(executable); - free(analyzer);
- char *formatted_backtrace = btp_core_backtrace_fmt(backtrace); - - dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (!dd) - xfunc_die(); - dd_save_text(dd, FILENAME_CORE_BACKTRACE, formatted_backtrace); - dd_close(dd); - - log(_("Core backtrace is generated and saved, %u bytes"), (int)strlen(formatted_backtrace)); - - free(formatted_backtrace); - btp_core_backtrace_free(backtrace); return 0; } - -#endif /* USE_SATYR */ diff --git a/src/plugins/koops_event.conf b/src/plugins/koops_event.conf index 7409922..9966775 100644 --- a/src/plugins/koops_event.conf +++ b/src/plugins/koops_event.conf @@ -3,7 +3,6 @@ EVENT=post-create analyzer=Kerneloops # >> instead of > is due to bugzilla.redhat.com/show_bug.cgi?id=854266 abrt-action-analyze-oops && dmesg >>dmesg && - abrt-action-generate-core-backtrace abrt-action-save-kernel-data
# If you want behavior similar to one provided by kerneloops daemon diff --git a/src/plugins/python_event.conf b/src/plugins/python_event.conf index 1aa0e99..3a45373 100644 --- a/src/plugins/python_event.conf +++ b/src/plugins/python_event.conf @@ -8,7 +8,6 @@ EVENT=post-create analyzer=Python exit 1 fi abrt-action-analyze-python - abrt-action-generate-core-backtrace
EVENT=report_Bugzilla analyzer=Python component!=anaconda test -f component || abrt-action-save-package-data diff --git a/src/plugins/vmcore_event.conf b/src/plugins/vmcore_event.conf index f6e260e..5d2d099 100644 --- a/src/plugins/vmcore_event.conf +++ b/src/plugins/vmcore_event.conf @@ -2,7 +2,6 @@ EVENT=analyze_VMcore analyzer=vmcore abrt-action-analyze-vmcore && abrt-action-analyze-oops && - abrt-action-generate-core-backtrace && abrt-action-save-kernel-data
# If you want behavior similar to one provided by kerneloops daemon
Signed-off-by: Martin Milata mmilata@redhat.com --- abrt.spec.in | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/abrt.spec.in b/abrt.spec.in index cff4338..4797062 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -62,10 +62,9 @@ BuildRequires: asciidoc BuildRequires: doxygen BuildRequires: xmlto BuildRequires: libreport-devel >= 2.1.3 -BuildRequires: btparser-devel -##satyr migration: -#BuildRequires: satyr-devel +BuildRequires: satyr-devel >= 0.4 Requires: libreport >= 2.1.3 +Requires: satyr >= 0.4 # these only exist on suse %if 0%{?suse_version} BuildRequires: dbus-1-glib-devel @@ -123,9 +122,7 @@ GTK+ wizard for convenient bug reporting. %package addon-ccpp Summary: %{name}'s C/C++ addon Group: System Environment/Libraries -Requires: cpio, btparser -##satyr migration: -#Requires: cpio, satyr +Requires: cpio Requires: gdb >= 7.0-3 Requires: elfutils # abrt-action-perform-ccpp-analysis wants to run analyze_RetraceServer:
Duplicate detection works. Pushed both. Thank you!
On Tue, 2013-07-09 at 18:16 +0200, Martin Milata wrote:
Closes abrt/satyr#88.
Signed-off-by: Martin Milata mmilata@redhat.com
configure.ac | 14 +- doc/abrt-action-generate-core-backtrace.txt | 50 +----- src/daemon/abrt-handle-event.c | 81 +++++----- src/include/Makefile.am | 1 - src/include/satyr-compat.h | 171 -------------------- src/plugins/abrt-action-analyze-backtrace.c | 41 +++-- src/plugins/abrt-action-generate-core-backtrace.c | 180 ++-------------------- src/plugins/koops_event.conf | 1 - src/plugins/python_event.conf | 1 - src/plugins/vmcore_event.conf | 1 - 10 files changed, 92 insertions(+), 449 deletions(-) delete mode 100644 src/include/satyr-compat.h
diff --git a/configure.ac b/configure.ac index ccd3901..7b32618 100644 --- a/configure.ac +++ b/configure.ac @@ -92,11 +92,6 @@ 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]) @@ -109,14 +104,7 @@ 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_CHECK_MODULES([SATYR], [satyr])
PKG_PROG_PKG_CONFIG AC_ARG_WITH([systemdsystemunitdir], diff --git a/doc/abrt-action-generate-core-backtrace.txt b/doc/abrt-action-generate-core-backtrace.txt index 0e68031..988327f 100644 --- a/doc/abrt-action-generate-core-backtrace.txt +++ b/doc/abrt-action-generate-core-backtrace.txt @@ -3,12 +3,11 @@ abrt-action-generate-core-backtrace(1)
NAME
-abrt-action-generate-core-backtrace - Generates coredump-level (debuginfo-free) -backtrace +abrt-action-generate-core-backtrace - Generates coredump-level backtrace
SYNOPSIS
-'abrt-action-generate-core-backtrace' [-v] [-d DIR] +'abrt-action-generate-core-backtrace' [-v] [-r] [-d DIR]
DESCRIPTION
@@ -22,8 +21,7 @@ However, it only contains information that can be obtained from the coredump without debugging symbols available - mainly relative addresses of the stored instruction pointers. Such backtrace can still be useful for reporting and reproducing the bug and does not require debugging -information files to be installed. See <<X1,*FILE FORMAT*>> for the -description of the generated file. +information files to be installed.
The result is saved in the problem directory in a file named 'core_backtrace'. @@ -45,48 +43,12 @@ OPTIONS -d DIR:: Path to problem directory.
+-r::
- Do not hash function fingerprints. Useful for debugging.
-v:: Be more verbose. Can be given multiple times.
-[[X1]]
-FILE FORMAT
-The generated file is a text file containing one line for each stack frame of -the thread that most likely caused the crash. The line has following format:
-BUILD_ID OFFSET SYMBOL MODNAME FINGERPRINT
-Where:
-*BUILD_ID*::
- Build ID of the binary file the address is mapped to as a hexadecimal string.
-*OFFSET*::
- Offset from the start of the executable section of aforementioned file the
- stored instruction pointer points to. Number in hexadecimal format.
-*SYMBOL*::
- Name of the function if it is present in the binary (which is often the case
- for shared libraries).
-*MODNAME*::
- Name of the module. Contains name of a library or *[exe]* if it is the
- executable.
-*FINGERPRINT*::
- Fingerprint of the function the instruction pointer points to (x86-64 only).
- The fingerprint is generated from various aspects of the machine code of the
- function in question. Its purpose is to supplant the BUILD_ID and OFFSET
- pair in case they are not present and to allow for comparison of
- coredump-level backtraces produced by two slightly different versions of a
- program.
-Dash in place of any of the parts indicates that the part is unknown.
AUTHORS
diff --git a/src/daemon/abrt-handle-event.c b/src/daemon/abrt-handle-event.c index a426566..eadb058 100644 --- a/src/daemon/abrt-handle-event.c +++ b/src/daemon/abrt-handle-event.c @@ -16,22 +16,42 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <satyr/thread.h> +#include <satyr/stacktrace.h> +#include <satyr/distance.h> +#include <satyr/abrt.h>
#include "libabrt.h" #include <libreport/run_event.h> -#include "satyr-compat.h"
+/* 70 % similarity */ +#define BACKTRACE_DUP_THRESHOLD 0.3
static char *uid = NULL; static char *uuid = NULL; -static struct sr_core_stacktrace *corebt = NULL; +static struct sr_stacktrace *corebt = NULL; +static char *analyzer = NULL; static char *crash_dump_dup_name = NULL;
-static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, +static char* load_backtrace(const struct dump_dir *dd) +{
- const char *filename = FILENAME_BACKTRACE;
- if (strcmp(analyzer, "CCpp") == 0)
- {
filename = FILENAME_CORE_BACKTRACE;
- }
- return dd_load_text_ext(dd, filename,
DD_FAIL_QUIETLY_ENOENT|DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
+}
+static int core_backtrace_is_duplicate(struct sr_stacktrace *bt1, const char *bt2_text) { int result; char *error_message;
- struct sr_core_stacktrace *bt2 = sr_core_stacktrace_from_json_text(bt2_text, &error_message);
- struct sr_stacktrace *bt2 = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer),
if (bt2 == NULL) { VERB1 log("Failed to parse backtrace, considering it not duplicate: %s", error_message);bt2_text, &error_message);
@@ -39,10 +59,10 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, return 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);
- struct sr_thread *thread1 = sr_stacktrace_find_crash_thread(bt1);
- struct sr_thread *thread2 = sr_stacktrace_find_crash_thread(bt2);
- int length2 = sr_core_thread_get_frame_count(thread2);
int length2 = sr_thread_frame_count(thread2);
if (length2 <= 0) {
@@ -52,7 +72,7 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, }
/* This is an ugly workaround for https://github.com/abrt/btparser/issues/6 */
-#ifndef USE_SATYR
/* int length1 = sr_core_thread_get_frame_count(thread1);
if (length1 <= 2 || length2 <= 2)
@@ -61,23 +81,14 @@ static int core_backtrace_is_duplicate(struct sr_core_stacktrace *bt1, result = (sr_core_thread_cmp(thread1, thread2) == 0); goto end; } -#endif
- float distance = sr_distance_core(SR_DISTANCE_DAMERAU_LEVENSHTEIN,
thread1, thread2);
- */
- if (distance == -1)
- {
result = 0;
- }
- else
- {
VERB2 log("Distance between backtraces: %f", distance);
result = (distance <= BACKTRACE_DUP_THRESHOLD);
- }
- float distance = sr_distance(SR_DISTANCE_DAMERAU_LEVENSHTEIN, thread1, thread2);
- VERB2 log("Distance between backtraces: %f", distance);
- result = (distance <= BACKTRACE_DUP_THRESHOLD);
end:
- sr_core_stacktrace_free(bt2);
sr_stacktrace_free(bt2);
return result;
} @@ -126,22 +137,17 @@ static void dup_uuid_fini(void)
static void dup_corebt_init(const struct dump_dir *dd) {
char *corebt_text;
if (corebt) return; /* already checked */
corebt_text = dd_load_text_ext(dd, FILENAME_CORE_BACKTRACE,
DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
);
char *corebt_text = load_backtrace(dd); if (!corebt_text) return; /* no backtrace */
/* sr_stacktrace_parse moves the pointer */ char *error_message;
- corebt = sr_core_stacktrace_from_json_text(corebt_text,
&error_message);
- corebt = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer),
if (!corebt) { VERB1 log("Failed to load core stacktrace: %s", error_message);corebt_text, &error_message);
@@ -157,9 +163,8 @@ static int dup_corebt_compare(const struct dump_dir *dd) return 0;
int isdup;
- char *dd_corebt = dd_load_text_ext(dd, FILENAME_CORE_BACKTRACE,
DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
- char *dd_corebt = load_backtrace(dd); if (!dd_corebt) return 0;
@@ -174,7 +179,7 @@ static int dup_corebt_compare(const struct dump_dir *dd)
static void dup_corebt_fini(void) {
- sr_core_stacktrace_free(corebt);
- sr_stacktrace_free(corebt); corebt = NULL;
}
@@ -208,13 +213,13 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param) if (!dd) return 0; /* wtf? (error, but will be handled elsewhere later) */
- dup_uuid_init(dd);
- dup_corebt_init(dd);
- char *analyzer = dd_load_text(dd, FILENAME_ANALYZER);
analyzer = dd_load_text(dd, FILENAME_ANALYZER); /* dump_dir_name can be relative */ dump_dir_name = realpath(dump_dir_name, NULL);
dup_uuid_init(dd);
dup_corebt_init(dd);
dd_close(dd);
DIR *dir = opendir(g_settings_dump_location);
diff --git a/src/include/Makefile.am b/src/include/Makefile.am index addbaa5..49a6f5c 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -5,5 +5,4 @@ libabrt_include_HEADERS = \ libabrt.h \ abrt-dbus.h \ hooklib.h \
- satyr-compat.h \ problem_api.h
diff --git a/src/include/satyr-compat.h b/src/include/satyr-compat.h deleted file mode 100644 index 23f6bb7..0000000 --- a/src/include/satyr-compat.h +++ /dev/null @@ -1,171 +0,0 @@ -/*
- 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.0
-/* abrt-handle-event.c */ -#define sr_core_stacktrace btp_thread -#define sr_core_thread btp_thread
-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);
-}
-int -sr_core_thread_cmp(struct sr_core_thread *thread1,
struct sr_core_thread *thread2)
-{
- return btp_thread_cmp(thread1, thread2);
-}
-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/abrt-action-analyze-backtrace.c b/src/plugins/abrt-action-analyze-backtrace.c index a980213..9348195 100644 --- a/src/plugins/abrt-action-analyze-backtrace.c +++ b/src/plugins/abrt-action-analyze-backtrace.c @@ -15,7 +15,11 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "satyr-compat.h" +#include <satyr/location.h> +#include <satyr/thread.h> +#include <satyr/gdb/frame.h> +#include <satyr/gdb/stacktrace.h>
#include "libabrt.h"
static const char *dump_dir_name = "."; @@ -130,18 +134,29 @@ int main(int argc, char **argv) }
/* Compute duplication hash. */
- 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);
- VERB3 log("Generating duphash: %s", str_hash->buf);
- char hash_str[SHA1_RESULT_LEN*2 + 1];
- create_hash(hash_str, str_hash->buf);
- dd_save_text(dd, FILENAME_DUPHASH, hash_str);
- strbuf_free(str_hash);
- free(str_hash_core);
struct sr_thread *crash_thread =
(struct sr_thread *)sr_gdb_stacktrace_find_crash_thread(backtrace);
if (crash_thread)
{
char *hash_str;
if (g_verbose >= 3)
{
hash_str = sr_thread_get_duphash(crash_thread, 3, component,
SR_DUPHASH_NOHASH);
log("Generating duphash: %s", hash_str);
free(hash_str);
}
hash_str = sr_thread_get_duphash(crash_thread, 3, component,
SR_DUPHASH_NORMAL);
dd_save_text(dd, FILENAME_DUPHASH, hash_str);
free(hash_str);
}
else
log(_("Crash thread not found"));
/* Compute the backtrace rating. */ float quality = sr_gdb_stacktrace_quality_complex(backtrace);
diff --git a/src/plugins/abrt-action-generate-core-backtrace.c b/src/plugins/abrt-action-generate-core-backtrace.c index 24d69cb..a549a53 100644 --- a/src/plugins/abrt-action-generate-core-backtrace.c +++ b/src/plugins/abrt-action-generate-core-backtrace.c @@ -16,74 +16,10 @@ with this program; if not, write to the Free Software Foundation, Inc., 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 <satyr/abrt.h> +#include <satyr/utils.h>
-#include <btparser/hash_sha1.h> -#include <btparser/utils.h> -#include <btparser/core-backtrace.h> -#include <btparser/core-backtrace-python.h> -#include <btparser/core-backtrace-oops.h>
-static bool raw_fingerprints = false;
-/* add the information about '?' flag to fingerprint field
- fingerprint is otherwise always empty for kerneloops */
-static void oops_add_question_marks(GList *backtrace) -{
- GList *elem = backtrace;
- struct backtrace_entry *entry;
- while (elem)
- {
entry = (struct backtrace_entry *)elem->data;
if (entry->function_initial_loc)
entry->fingerprint = btp_strdup("?");
elem = g_list_next(elem);
- }
-}
-static void hash_fingerprints(GList *backtrace) -{
- GList *elem = backtrace;
- struct backtrace_entry *entry;
- char bin_hash[BTP_SHA1_RESULT_BIN_LEN], hash[BTP_SHA1_RESULT_LEN];
- btp_sha1_ctx_t ctx;
- while (elem)
- {
entry = (struct backtrace_entry *)elem->data;
if (entry->fingerprint)
{
btp_sha1_begin(&ctx);
btp_sha1_hash(&ctx, entry->fingerprint, strlen(entry->fingerprint));
btp_sha1_end(&ctx, bin_hash);
btp_bin2hex(hash, bin_hash, sizeof(bin_hash))[0] = '\0';
free(entry->fingerprint);
entry->fingerprint = btp_strndup(hash, sizeof(hash));
}
elem = g_list_next(elem);
- }
-} +#include "libabrt.h"
int main(int argc, char **argv) { @@ -97,12 +33,11 @@ int main(int argc, char **argv) abrt_init(argv);
const char *dump_dir_name = ".";
- /* 60 seconds was too limiting on slow machines */
- const int exec_timeout_sec = 240;
bool raw_fingerprints = false;
/* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _(
"& [-v] -d DIR\n"
);"& [-v] [-r] -d DIR\n" "\n" "Creates coredump-level backtrace from core dump and corresponding binary"
@@ -123,109 +58,22 @@ int main(int argc, char **argv) export_abrt_envvars(0);
if (g_verbose > 1)
btp_debug_parser = true;
sr_debug_parser = true;
/* Let user know what's going on */ log(_("Generating core_backtrace"));
- /* Get the executable name -- unstrip doesn't know it. */
- struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
- if (!dd)
xfunc_die(); /* dd_opendir already printed error msg */
- char *analyzer = dd_load_text(dd, FILENAME_ANALYZER);
- char *executable = dd_load_text_ext(dd, FILENAME_EXECUTABLE,
DD_FAIL_QUIETLY_ENOENT);
- char *txt_backtrace = dd_load_text_ext(dd, FILENAME_BACKTRACE,
DD_FAIL_QUIETLY_ENOENT);
- char *kernel = dd_load_text_ext(dd, FILENAME_KERNEL,
DD_FAIL_QUIETLY_ENOENT |
DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
- dd_close(dd);
- /* Parse addresses and eventual symbols from the output */
- GList *backtrace;
- if (strcmp(analyzer, "CCpp") == 0)
- {
char *gdb_out = get_backtrace(dump_dir_name, exec_timeout_sec, NULL);
if (gdb_out == NULL)
xfunc_die();
/* We observed a case when we were stuck for 36 minutes after emitting
* "Generating backtrace" message (in get_backtrace).
* We don't know whether we finished bt generation
* and were stuck somewhere below this point, or we were stuck
* in get_backtrace(). For now, we emit this message
* even in non-verbose mode to aid in future debugging:
*/
log(_("Backtrace is generated, %u bytes"), (int)strlen(gdb_out));
backtrace = btp_backtrace_extract_addresses(gdb_out);
VERB1 log("Extracted %d frames from the backtrace", g_list_length(backtrace));
free(gdb_out);
- char *error_message = NULL;
- bool success = sr_abrt_create_core_stacktrace(dump_dir_name,
!raw_fingerprints,
&error_message);
VERB1 log("Running eu-unstrip -n to obtain build ids");
/* Run eu-unstrip -n to obtain the ids. This should be rewritten to read
* them directly from the core. */
char *unstrip_output = run_unstrip_n(dump_dir_name, /*timeout_sec:*/ 30);
if (unstrip_output == NULL)
error_msg_and_die("Running eu-unstrip failed");
btp_core_assign_build_ids(backtrace, unstrip_output, executable);
free(unstrip_output);
/* Remove empty lines from the backtrace. */
GList *loop = backtrace;
while (loop != NULL)
{
struct backtrace_entry *entry = loop->data;
GList *const tmp_next = g_list_next(loop);
if (!entry->build_id && !entry->filename && !entry->modname)
backtrace = g_list_delete_link(backtrace, loop);
loop = tmp_next;
}
/* Extract address ranges from all the executables in the backtrace */
VERB1 log("Computing function fingerprints");
btp_core_backtrace_fingerprint(backtrace);
if (!raw_fingerprints)
hash_fingerprints(backtrace);
- }
- else if (strcmp(analyzer, "Python") == 0)
backtrace = btp_parse_python_backtrace(txt_backtrace);
- else if (strcmp(analyzer, "Kerneloops") == 0 || strcmp(analyzer, "vmcore") == 0)
- if (!success) {
/* btp_parse_kerneloops() accepts NULL in the kernelver argument. It is not
* documented, but it is true. */
if (kernel != NULL)
{
char *space = strchr(kernel, ' ');
if (space)
*space = '\0';
}
backtrace = btp_parse_kerneloops(txt_backtrace, kernel);
oops_add_question_marks(backtrace);
log(_("Error: %s"), error_message);
free(error_message);
}return 1;
else
error_msg_and_die(_("Core-backtraces are not supported for '%s'"), analyzer);
free(txt_backtrace);
free(kernel);
free(executable);
free(analyzer);
char *formatted_backtrace = btp_core_backtrace_fmt(backtrace);
dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
xfunc_die();
dd_save_text(dd, FILENAME_CORE_BACKTRACE, formatted_backtrace);
dd_close(dd);
log(_("Core backtrace is generated and saved, %u bytes"), (int)strlen(formatted_backtrace));
free(formatted_backtrace);
btp_core_backtrace_free(backtrace); return 0;
}
-#endif /* USE_SATYR */ diff --git a/src/plugins/koops_event.conf b/src/plugins/koops_event.conf index 7409922..9966775 100644 --- a/src/plugins/koops_event.conf +++ b/src/plugins/koops_event.conf @@ -3,7 +3,6 @@ EVENT=post-create analyzer=Kerneloops # >> instead of > is due to bugzilla.redhat.com/show_bug.cgi?id=854266 abrt-action-analyze-oops && dmesg >>dmesg &&
abrt-action-generate-core-backtrace abrt-action-save-kernel-data
# If you want behavior similar to one provided by kerneloops daemon diff --git a/src/plugins/python_event.conf b/src/plugins/python_event.conf index 1aa0e99..3a45373 100644 --- a/src/plugins/python_event.conf +++ b/src/plugins/python_event.conf @@ -8,7 +8,6 @@ EVENT=post-create analyzer=Python exit 1 fi abrt-action-analyze-python
abrt-action-generate-core-backtrace
EVENT=report_Bugzilla analyzer=Python component!=anaconda test -f component || abrt-action-save-package-data diff --git a/src/plugins/vmcore_event.conf b/src/plugins/vmcore_event.conf index f6e260e..5d2d099 100644 --- a/src/plugins/vmcore_event.conf +++ b/src/plugins/vmcore_event.conf @@ -2,7 +2,6 @@ EVENT=analyze_VMcore analyzer=vmcore abrt-action-analyze-vmcore && abrt-action-analyze-oops &&
abrt-action-generate-core-backtrace && abrt-action-save-kernel-data
# If you want behavior similar to one provided by kerneloops daemon
crash-catcher@lists.fedorahosted.org