diff options
author | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-11-15 15:12:35 +0100 |
---|---|---|
committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-11-15 15:12:35 +0100 |
commit | 4fcc8ac7f38a2b400f22b467a4b03ac747483f99 (patch) | |
tree | ed3196bb7ba7730f87fdbd586ecda1d65b6abfd5 /lib/Plugins | |
parent | c90533a0d201788199a8f0c922d5ba75af75f2f0 (diff) | |
download | abrt-4fcc8ac7f38a2b400f22b467a4b03ac747483f99.tar.gz abrt-4fcc8ac7f38a2b400f22b467a4b03ac747483f99.tar.xz abrt-4fcc8ac7f38a2b400f22b467a4b03ac747483f99.zip |
new bt parser (kklic)
Diffstat (limited to 'lib/Plugins')
-rw-r--r-- | lib/Plugins/CCpp.cpp | 256 | ||||
-rw-r--r-- | lib/Plugins/Makefile.am | 2 |
2 files changed, 64 insertions, 194 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 587ff380..3dbd73e1 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -31,8 +31,10 @@ #if 0 #include "Polkit.h" #endif -#include "backtrace.h" #include "CCpp_sha1.h" +#include "../btparser/backtrace.h" +#include "../btparser/frame.h" +#include "../btparser/location.h" using namespace std; @@ -562,120 +564,7 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) return uuid; } else - { - // Compatibility code. - // This whole block should be deleted for Fedora 14. - log(_("Getting global universal unique identification...")); - - string backtrace_path = concat_path_file(pDebugDumpDir, FILENAME_BACKTRACE); - string executable; - string package; - string uid_str; - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - if (m_bBacktrace) - dd.LoadText(CD_UID, uid_str); - - string independent_backtrace; - if (m_bBacktrace) - { - /* Run abrt-backtrace to get independent backtrace suitable - to UUID calculation. */ - char *args[7]; - args[0] = (char*)"abrt-backtrace"; - args[1] = (char*)"--single-thread"; - args[2] = (char*)"--remove-exit-handlers"; - args[3] = (char*)"--frame-depth=5"; - args[4] = (char*)"--remove-noncrash-frames"; - args[5] = (char*)backtrace_path.c_str(); - args[6] = NULL; - - int pipeout[2]; - xpipe(pipeout); /* stdout of abrt-backtrace */ - - fflush(NULL); - pid_t child = fork(); - if (child == -1) - perror_msg_and_die("fork"); - if (child == 0) - { - VERB1 log("Executing %s", args[0]); - - xmove_fd(pipeout[1], STDOUT_FILENO); - close(pipeout[0]); /* read side of the pipe */ - - /* abrt-backtrace is executed under the user's uid and gid. */ - uid_t uid = xatoi_u(uid_str.c_str()); - struct passwd* pw = getpwuid(uid); - gid_t gid = pw ? pw->pw_gid : uid; - setgroups(1, &gid); - xsetregid(gid, gid); - xsetreuid(uid, uid); - - execvp(args[0], args); - VERB1 perror_msg("Can't execute '%s'", args[0]); - exit(1); - } - - close(pipeout[1]); /* write side of the pipe */ - - /* Read the result from abrt-backtrace. */ - int r; - char buff[1024]; - while ((r = safe_read(pipeout[0], buff, sizeof(buff) - 1)) > 0) - { - buff[r] = '\0'; - independent_backtrace += buff; - } - close(pipeout[0]); - - /* Wait until it exits, and check the exit status. */ - errno = 0; - int status; - waitpid(child, &status, 0); - if (!WIFEXITED(status)) - { - perror_msg("abrt-backtrace not executed properly, " - "status: %x signal: %d", status, WIFSIGNALED(status)); - } - else - { - int exit_status = WEXITSTATUS(status); - if (exit_status == 79) /* EX_PARSINGFAILED */ - { - /* abrt-backtrace returns alternative backtrace - representation in this case, so everything will work - as expected except worse duplication detection */ - log_msg("abrt-backtrace failed to parse the backtrace"); - } - else if (exit_status == 80) /* EX_THREADDETECTIONFAILED */ - { - /* abrt-backtrace returns backtrace with all threads - in this case, so everything will work as expected - except worse duplication detection */ - log_msg("abrt-backtrace failed to determine crash frame"); - } - else if (exit_status != 0) - { - /* this is unexpected problem and it should be investigated */ - error_msg("abrt-backtrace run failed, exit value: %d", - exit_status); - } - } - - /*VERB1 log("abrt-backtrace result: %s", independent_backtrace.c_str());*/ - } - /* else: no backtrace, independent_backtrace == "" - no backtrace => rating = 0 - */ - else - { - dd.SaveText(FILENAME_RATING, "0"); - } - - string hash_base = package + executable + independent_backtrace; - return create_hash(hash_base.c_str()); - } + return ""; } #if 0 static bool DebuginfoCheckPolkit(uid_t uid) @@ -759,87 +648,68 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) if (m_bMemoryMap) dd.SaveText(FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet"); - /* Compute and store UUID from the backtrace. */ - char *backtrace_cpy = xstrdup(backtrace_str.c_str()); - struct backtrace *backtrace = backtrace_parse(backtrace_cpy, false, false); - free(backtrace_cpy); - if (backtrace) - { - /* Get the quality of the full backtrace. */ - float q1 = backtrace_quality(backtrace); + /* Compute and store backtrace hash. */ + struct btp_location location; + btp_location_init(&location); + char *backtrace_str_ptr = (char*)backtrace_str.c_str(); + struct btp_backtrace *backtrace = btp_backtrace_parse(&backtrace_str_ptr, &location); + if (!backtrace) + { + VERB1 log(_("Backtrace parsing failed for %s"), pDebugDumpDir); + VERB1 log("%d:%d: %s", location.line, location.column, location.message); + /* If the parser failed compute the UUID from the executable + and package only. This is not supposed to happen often. + Do not store the rating, as we do not know how good the + backtrace is. */ + struct strbuf *emptybt = strbuf_new(); + strbuf_prepend_str(emptybt, executable.c_str()); + strbuf_prepend_str(emptybt, package.c_str()); + string hash_str = create_hash(emptybt->buf); + dd.SaveText(FILENAME_GLOBAL_UUID, hash_str.c_str()); + + strbuf_free(emptybt); + dd.Close(); + return; + } - /* Remove all the other threads except the crash thread. */ - struct thread *crash_thread = backtrace_find_crash_thread(backtrace); - if (crash_thread) - backtrace_remove_threads_except_one(backtrace, crash_thread); - else - log_msg("Detection of crash thread failed"); - - /* Get the quality of the crash thread. */ - float q2 = backtrace_quality(backtrace); - - backtrace_remove_noncrash_frames(backtrace); - - /* Do the frame removal now. */ - backtrace_limit_frame_depth(backtrace, 5); - /* Frame removal can be done before removing exit handlers. */ - backtrace_remove_exit_handlers(backtrace); - - /* Get the quality of frames around the crash. */ - float q3 = backtrace_quality(backtrace); - - /* Compute UUID. */ - struct strbuf *bt = backtrace_tree_as_str(backtrace, false); - strbuf_prepend_str(bt, executable.c_str()); - strbuf_prepend_str(bt, package.c_str()); - dd.SaveText(FILENAME_GLOBAL_UUID, create_hash(bt->buf).c_str()); - strbuf_free(bt); - - /* Compute and store backtrace rating. */ - /* Compute and store backtrace rating. The crash frame - is more important that the others. The frames around - the crash are more important than the rest. */ - float qtot = 0.25f * q1 + 0.35f * q2 + 0.4f * q3; - - /* Turn the quality to rating. */ - const char *rating; - if (qtot < 0.6f) rating = "0"; - else if (qtot < 0.7f) rating = "1"; - else if (qtot < 0.8f) rating = "2"; - else if (qtot < 0.9f) rating = "3"; - else rating = "4"; - dd.SaveText(FILENAME_RATING, rating); - - /* Get the function name from the crash frame. */ - if (crash_thread) + /* 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.c_str()); + strbuf_append_str(str_hash, executable.c_str()); + strbuf_append_str(str_hash, str_hash_core); + string hash_str = create_hash(str_hash->buf); + dd.SaveText(FILENAME_GLOBAL_UUID, hash_str.c_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.SaveText(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, "??")) { - struct frame *crash_frame = crash_thread->frames; - struct frame *abort_frame = thread_find_abort_frame(crash_thread); - if (abort_frame) - crash_frame = abort_frame->next; - if (crash_frame && crash_frame->function && 0 != strcmp(crash_frame->function, "??")) - dd.SaveText(FILENAME_CRASH_FUNCTION, crash_frame->function); + dd.SaveText(FILENAME_CRASH_FUNCTION, crash_frame->function_name); } - - backtrace_free(backtrace); - } - else - { - /* If the parser failed fall back to the independent backtrace. */ - /* If we write and use a hand-written parser instead of the bison one, - the parser never fails, and it will be possible to get rid of - the independent_backtrace and backtrace_rate_old. */ - struct strbuf *ibt = independent_backtrace(backtrace_str.c_str()); - strbuf_prepend_str(ibt, executable.c_str()); - strbuf_prepend_str(ibt, package.c_str()); - dd.SaveText(FILENAME_GLOBAL_UUID, create_hash(ibt->buf).c_str()); - strbuf_free(ibt); - - /* Compute and store backtrace rating. */ - /* Crash frame is not known so store nothing. */ - dd.SaveText(FILENAME_RATING, to_string(backtrace_rate_old(backtrace_str.c_str())).c_str()); - } - + btp_frame_free(crash_frame); + } + btp_backtrace_free(backtrace); dd.Close(); } diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am index cc00186d..a2c494be 100644 --- a/lib/Plugins/Makefile.am +++ b/lib/Plugins/Makefile.am @@ -63,7 +63,7 @@ install-data-hook: $(DESTDIR)/$(DEBUG_INFO_DIR) # CCpp libCCpp_la_SOURCES = CCpp.cpp CCpp.h CCpp_sha1.cpp CCpp_sha1.h libCCpp_la_LDFLAGS = -avoid-version -#libCCpp_la_LIBADD = +libCCpp_la_LIBADD = ../btparser/libbtparser.la libCCpp_la_CPPFLAGS = -I$(srcdir)/../../inc -I$(srcdir)/../Utils \ -DCCPP_HOOK_PATH=\"${libexecdir}/abrt-hook-ccpp\" \ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ |