summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarel Klic <kklic@redhat.com>2011-03-26 15:01:47 +0100
committerJiri Moskovcak <jmoskovc@redhat.com>2011-03-26 15:21:15 +0100
commitdd11716e5c6c3e2589dfc6440e131a06d7eecd3a (patch)
treefc67c49e94f6c8afe71d22b93abee94af61e031c /src
parent508e1d6585a37483cc5166824840fd6be776869d (diff)
downloadabrt-dd11716e5c6c3e2589dfc6440e131a06d7eecd3a.tar.gz
abrt-dd11716e5c6c3e2589dfc6440e131a06d7eecd3a.tar.xz
abrt-dd11716e5c6c3e2589dfc6440e131a06d7eecd3a.zip
Analyze backtraces from retrace server
Hi, the attached patch splits a part of abrt-action-generate-backtrace to a new tool abrt-action-analyze-backtrace, which is used by both LocalGDB and RetraceServer analyzers. Then new abrt-action-analyze-backtrace tool reads backtrace and generates duplication hash, detects crash function, and provides backtrace rating. These steps haven't been performed for remotely analyzed crashes so far. Karel
Diffstat (limited to 'src')
-rw-r--r--src/plugins/Makefile.am20
-rw-r--r--src/plugins/abrt-action-analyze-backtrace.c190
-rw-r--r--src/plugins/abrt-action-generate-backtrace.c131
-rw-r--r--src/plugins/ccpp_events.conf6
4 files changed, 222 insertions, 125 deletions
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 8dd618e6..5344cdb4 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -11,6 +11,7 @@ bin_PROGRAMS = \
abrt-action-analyze-oops \
abrt-action-trim-files \
abrt-action-generate-backtrace \
+ abrt-action-analyze-backtrace \
abrt-action-bugzilla \
abrt-action-rhtsupport \
abrt-action-kerneloops \
@@ -179,6 +180,25 @@ abrt_action_generate_backtrace_CPPFLAGS = \
-D_GNU_SOURCE \
-Wall -Wwrite-strings -Werror
abrt_action_generate_backtrace_LDADD = \
+ ../lib/libreport.la
+
+abrt_action_analyze_backtrace_SOURCES = \
+ abrt-action-analyze-backtrace.c
+abrt_action_analyze_backtrace_CPPFLAGS = \
+ -I$(srcdir)/../include/report -I$(srcdir)/../include \
+ -I$(srcdir)/../lib \
+ -DBIN_DIR=\"$(bindir)\" \
+ -DVAR_RUN=\"$(VAR_RUN)\" \
+ -DCONF_DIR=\"$(CONF_DIR)\" \
+ -DLOCALSTATEDIR='"$(localstatedir)"' \
+ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
+ -DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \
+ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
+ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
+ $(GLIB_CFLAGS) \
+ -D_GNU_SOURCE \
+ -Wall -Wwrite-strings -Werror
+abrt_action_analyze_backtrace_LDADD = \
../lib/libreport.la \
../btparser/libbtparser.la
diff --git a/src/plugins/abrt-action-analyze-backtrace.c b/src/plugins/abrt-action-analyze-backtrace.c
new file mode 100644
index 00000000..e65b1781
--- /dev/null
+++ b/src/plugins/abrt-action-analyze-backtrace.c
@@ -0,0 +1,190 @@
+/*
+ Copyright (C) 2010, 2011 Red Hat, 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.
+*/
+#include "abrtlib.h"
+#include "../btparser/backtrace.h"
+#include "../btparser/frame.h"
+#include "../btparser/location.h"
+#include "parse_options.h"
+
+#define PROGNAME "abrt-action-generate-backtrace"
+
+static const char *dump_dir_name = ".";
+
+
+static void create_hash(char hash_str[SHA1_RESULT_LEN*2 + 1], const char *pInput)
+{
+ unsigned len;
+ unsigned char hash2[SHA1_RESULT_LEN];
+ sha1_ctx_t sha1ctx;
+
+ sha1_begin(&sha1ctx);
+ sha1_hash(pInput, strlen(pInput), &sha1ctx);
+ sha1_end(hash2, &sha1ctx);
+ len = SHA1_RESULT_LEN;
+
+ char *d = hash_str;
+ unsigned char *s = hash2;
+ while (len)
+ {
+ *d++ = "0123456789abcdef"[*s >> 4];
+ *d++ = "0123456789abcdef"[*s & 0xf];
+ s++;
+ len--;
+ }
+ *d = '\0';
+ //log("hash2:%s str:'%s'", hash_str, pInput);
+}
+
+int main(int argc, char **argv)
+{
+ char *env_verbose = getenv("ABRT_VERBOSE");
+ if (env_verbose)
+ g_verbose = atoi(env_verbose);
+
+ /* Can't keep these strings/structs static: _() doesn't support that */
+ const char *program_usage_string = _(
+ PROGNAME" [options] -d DIR\n"
+ "\n"
+ "Analyzes C/C++ backtrace, generates duplication hash, backtrace rating, and identifies crash function in dump directory DIR"
+ );
+ enum {
+ OPT_v = 1 << 0,
+ OPT_d = 1 << 1
+ };
+ /* Keep enum above and order of options below in sync! */
+ struct options program_options[] = {
+ OPT__VERBOSE(&g_verbose),
+ OPT_STRING('d', NULL, &dump_dir_name, "DIR", _("Dump directory")),
+ OPT_END()
+ };
+ /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string);
+
+ putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
+
+ char *pfx = getenv("ABRT_PROG_PREFIX");
+ if (pfx && string_to_bool(pfx))
+ msg_prefix = PROGNAME;
+
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ if (!dd)
+ return 1;
+
+ char *package = dd_load_text(dd, FILENAME_PACKAGE);
+ char *executable = dd_load_text(dd, FILENAME_EXECUTABLE);
+
+ /* Read backtrace */
+ /* NB: get_backtrace() closes dd */
+ char *backtrace_str = dd_load_text(dd, FILENAME_BACKTRACE);
+ if (!backtrace_str)
+ {
+ backtrace_str = xstrdup("");
+ log("Backtrace file is missing");
+ }
+
+ /* Compute backtrace hash */
+ struct btp_location location;
+ btp_location_init(&location);
+ char *backtrace_str_ptr = backtrace_str;
+ struct btp_backtrace *backtrace = btp_backtrace_parse(&backtrace_str_ptr, &location);
+ free(backtrace_str);
+
+ /* Store backtrace hash */
+ if (!backtrace)
+ {
+ /*
+ * The parser failed. Compute the UUID from the executable
+ * and package only. This is not supposed to happen often.
+ */
+ VERB1 log(_("Backtrace parsing failed for %s"), dump_dir_name);
+ VERB1 log("%d:%d: %s", location.line, location.column, location.message);
+ struct strbuf *emptybt = strbuf_new();
+ strbuf_prepend_str(emptybt, executable);
+ strbuf_prepend_str(emptybt, package);
+
+ char hash_str[SHA1_RESULT_LEN*2 + 1];
+ create_hash(hash_str, emptybt->buf);
+
+ dd_save_text(dd, FILENAME_DUPHASH, hash_str);
+ /*
+ * Other parts of ABRT assume that if no rating is available,
+ * it is ok to allow reporting of the bug. To be sure no bad
+ * backtrace is reported, rate the backtrace with the lowest
+ * rating.
+ */
+ dd_save_text(dd, FILENAME_RATING, "0");
+
+ strbuf_free(emptybt);
+ free(package);
+ free(executable);
+ dd_close(dd);
+
+ /* Report success even if the parser failed, as the backtrace
+ * has been created and rated. The failure is caused by a flaw
+ * in the parser, not in the backtrace.
+ */
+ return 0;
+ }
+
+ /* Compute duplication hash. */
+ char *str_hash_core = btp_backtrace_get_duplication_hash(backtrace);
+ struct strbuf *str_hash = strbuf_new();
+ strbuf_append_str(str_hash, package);
+ strbuf_append_str(str_hash, executable);
+ strbuf_append_str(str_hash, str_hash_core);
+
+ 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);
+
+ /* Compute the backtrace rating. */
+ float quality = btp_backtrace_quality_complex(backtrace);
+ const char *rating;
+ if (quality < 0.6f)
+ rating = "0";
+ else if (quality < 0.7f)
+ rating = "1";
+ else if (quality < 0.8f)
+ rating = "2";
+ else if (quality < 0.9f)
+ rating = "3";
+ else
+ rating = "4";
+ dd_save_text(dd, FILENAME_RATING, rating);
+
+ /* Get the function name from the crash frame. */
+ struct btp_frame *crash_frame = btp_backtrace_get_crash_frame(backtrace);
+ if (crash_frame)
+ {
+ if (crash_frame->function_name &&
+ 0 != strcmp(crash_frame->function_name, "??"))
+ {
+ dd_save_text(dd, FILENAME_CRASH_FUNCTION, crash_frame->function_name);
+ }
+ btp_frame_free(crash_frame);
+ }
+ btp_backtrace_free(backtrace);
+ dd_close(dd);
+
+ free(executable);
+ free(package);
+
+ return 0;
+}
diff --git a/src/plugins/abrt-action-generate-backtrace.c b/src/plugins/abrt-action-generate-backtrace.c
index 0c2d9a0a..5afe6e43 100644
--- a/src/plugins/abrt-action-generate-backtrace.c
+++ b/src/plugins/abrt-action-generate-backtrace.c
@@ -1,6 +1,6 @@
/*
Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
- Copyright (C) 2009 RedHat inc.
+ Copyright (C) 2009 Red Hat, 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
@@ -33,30 +33,6 @@ static const char *debuginfo_dirs = DEBUGINFO_CACHE_DIR;
static int exec_timeout_sec = 240;
-static void create_hash(char hash_str[SHA1_RESULT_LEN*2 + 1], const char *pInput)
-{
- unsigned len;
- unsigned char hash2[SHA1_RESULT_LEN];
- sha1_ctx_t sha1ctx;
-
- sha1_begin(&sha1ctx);
- sha1_hash(pInput, strlen(pInput), &sha1ctx);
- sha1_end(hash2, &sha1ctx);
- len = SHA1_RESULT_LEN;
-
- char *d = hash_str;
- unsigned char *s = hash2;
- while (len)
- {
- *d++ = "0123456789abcdef"[*s >> 4];
- *d++ = "0123456789abcdef"[*s & 0xf];
- s++;
- len--;
- }
- *d = '\0';
- //log("hash2:%s str:'%s'", hash_str, pInput);
-}
-
/**
*
* @param[out] status See `man 2 wait` for status information.
@@ -299,119 +275,26 @@ int main(int argc, char **argv)
if (!dd)
return 1;
- char *package = dd_load_text(dd, FILENAME_PACKAGE);
- char *executable = dd_load_text(dd, FILENAME_EXECUTABLE);
-
/* Create gdb backtrace */
/* NB: get_backtrace() closes dd */
- char *backtrace_str = get_backtrace(dd);
- if (!backtrace_str)
+ char *backtrace = get_backtrace(dd);
+ if (!backtrace)
{
- backtrace_str = xstrdup("");
+ backtrace = xstrdup("");
log("get_backtrace() returns NULL, broken core/gdb?");
}
- /* Compute backtrace hash */
- struct btp_location location;
- btp_location_init(&location);
- char *backtrace_str_ptr = backtrace_str;
- struct btp_backtrace *backtrace = btp_backtrace_parse(&backtrace_str_ptr, &location);
-
/* Store gdb backtrace */
dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
return 1;
- dd_save_text(dd, FILENAME_BACKTRACE, backtrace_str);
+ dd_save_text(dd, FILENAME_BACKTRACE, backtrace);
/* Don't be completely silent. gdb run takes a few seconds,
* it is useful to let user know it (maybe) worked.
*/
- log(_("Backtrace is generated and saved, %u bytes"), (int)strlen(backtrace_str));
- free(backtrace_str);
-
- /* Store backtrace hash */
-
- if (!backtrace)
- {
- /*
- * The parser failed. Compute the UUID from the executable
- * and package only. This is not supposed to happen often.
- */
- VERB1 log(_("Backtrace parsing failed for %s"), dump_dir_name);
- VERB1 log("%d:%d: %s", location.line, location.column, location.message);
- struct strbuf *emptybt = strbuf_new();
- strbuf_prepend_str(emptybt, executable);
- strbuf_prepend_str(emptybt, package);
-
- char hash_str[SHA1_RESULT_LEN*2 + 1];
- create_hash(hash_str, emptybt->buf);
-
- dd_save_text(dd, FILENAME_DUPHASH, hash_str);
- /*
- * Other parts of ABRT assume that if no rating is available,
- * it is ok to allow reporting of the bug. To be sure no bad
- * backtrace is reported, rate the backtrace with the lowest
- * rating.
- */
- dd_save_text(dd, FILENAME_RATING, "0");
-
- strbuf_free(emptybt);
- free(package);
- free(executable);
- dd_close(dd);
-
- /* Report success even if the parser failed, as the backtrace
- * has been created and rated. The failure is caused by a flaw
- * in the parser, not in the backtrace.
- */
- return 0;
- }
-
- /* Compute duplication hash. */
- char *str_hash_core = btp_backtrace_get_duplication_hash(backtrace);
- struct strbuf *str_hash = strbuf_new();
- strbuf_append_str(str_hash, package);
- strbuf_append_str(str_hash, executable);
- strbuf_append_str(str_hash, str_hash_core);
-
- 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);
-
- /* Compute the backtrace rating. */
- float quality = btp_backtrace_quality_complex(backtrace);
- const char *rating;
- if (quality < 0.6f)
- rating = "0";
- else if (quality < 0.7f)
- rating = "1";
- else if (quality < 0.8f)
- rating = "2";
- else if (quality < 0.9f)
- rating = "3";
- else
- rating = "4";
- dd_save_text(dd, FILENAME_RATING, rating);
-
- /* Get the function name from the crash frame. */
- struct btp_frame *crash_frame = btp_backtrace_get_crash_frame(backtrace);
- if (crash_frame)
- {
- if (crash_frame->function_name &&
- 0 != strcmp(crash_frame->function_name, "??"))
- {
- dd_save_text(dd, FILENAME_CRASH_FUNCTION, crash_frame->function_name);
- }
- btp_frame_free(crash_frame);
- }
- btp_backtrace_free(backtrace);
- dd_close(dd);
-
- free(executable);
- free(package);
+ log(_("Backtrace is generated and saved, %u bytes"), (int)strlen(backtrace));
+ free(backtrace);
return 0;
}
diff --git a/src/plugins/ccpp_events.conf b/src/plugins/ccpp_events.conf
index 0698e655..8a5f377e 100644
--- a/src/plugins/ccpp_events.conf
+++ b/src/plugins/ccpp_events.conf
@@ -7,13 +7,17 @@ EVENT=analyze_LocalGDB analyzer=CCpp backtrace= abrt-action-trim-files -f 4
# or was this ability lost with move to python installer?
EVENT=analyze_LocalGDB analyzer=CCpp backtrace= abrt-action-install-debuginfo --core="$DUMP_DIR/coredump"
EVENT=analyze_LocalGDB analyzer=CCpp backtrace= abrt-action-generate-backtrace
-EVENT=analyze_RetraceServer analyzer=CCpp backtrace= abrt-retrace-client batch -k --dir "$DUMP_DIR"
+EVENT=analyze_LocalGDB analyzer=CCpp backtrace= abrt-action-analyze-backtrace
+EVENT=analyze_RetraceServer analyzer=CCpp backtrace= abrt-retrace-client batch -k --dir "$DUMP_DIR"
+EVENT=analyze_RetraceServer analyzer=CCpp backtrace= abrt-action-analyze-backtrace
# Same as "analyze", but executed when user requests "refresh" in GUI
# It doesn't check that backtrace is empty:
EVENT=reanalyze_LocalGDB analyzer=CCpp abrt-action-trim-files -f 4096m:/var/cache/abrt-di
EVENT=reanalyze_LocalGDB analyzer=CCpp abrt-action-install-debuginfo --core="$DUMP_DIR/coredump"
EVENT=reanalyze_LocalGDB analyzer=CCpp abrt-action-generate-backtrace
+EVENT=reanalyze_LocalGDB analyzer=CCpp abrt-action-analyze-backtrace
EVENT=reanalyze_RetraceServer analyzer=CCpp abrt-retrace-client batch -k --dir "$DUMP_DIR"
+EVENT=reanalyze_RetraceServer analyzer=CCpp abrt-action-analyze-backtrace
EVENT=report_Bugzilla analyzer=CCpp abrt-action-bugzilla -c /etc/abrt/plugins/Bugzilla.conf