Blame SOURCES/0034-Use-satyr-for-calculation-of-the-duplicates-hashes.patch

23d3c3
From 9801d36ca38a03c69a92689fdcb37afde01dc066 Mon Sep 17 00:00:00 2001
23d3c3
From: Jakub Filak <jfilak@redhat.com>
23d3c3
Date: Mon, 20 Jan 2014 09:46:33 +0100
23d3c3
Subject: [PATCH 34/39] Use satyr for calculation of the duplicates hashes
23d3c3
23d3c3
The current algorithm simply hashes the entire backtrace file. This
23d3c3
approach results in non-working deduplication because the duplicate hash
23d3c3
depends on file system paths and line numbers.
23d3c3
23d3c3
Satyr provide a function for generating of reliable hashes where only
23d3c3
function names (in case of Java it means exception type too) are used
23d3c3
for input of the hash function.
23d3c3
23d3c3
Related to #29
23d3c3
Related to rhbz#1054737
23d3c3
---
23d3c3
 etc/java_event.conf                                |   8 -
23d3c3
 test/outputs/not_reportable_1remote_class.log.in   |   5 +
23d3c3
 test/outputs/not_reportable_3remote_classes.log.in |   5 +
23d3c3
 utils/abrt-action-analyze-java.c                   | 195 +++++++++++++--------
23d3c3
 4 files changed, 136 insertions(+), 77 deletions(-)
23d3c3
23d3c3
diff --git a/etc/java_event.conf b/etc/java_event.conf
23d3c3
index 302cac0..6014e93 100644
23d3c3
--- a/etc/java_event.conf
23d3c3
+++ b/etc/java_event.conf
23d3c3
@@ -8,14 +8,6 @@ EVENT=post-create type=Java
23d3c3
             # abrtd will delete the problem directory when we exit nonzero:
23d3c3
             exit 1
23d3c3
         fi
23d3c3
-        # TODO: Replace lines below by something more sane once abrt switches to satyr
23d3c3
-        if [ -f backtrace ]; then
23d3c3
-            printf '%s' "`sha1sum < "backtrace" | cut -d" " -f1`" > "uuid"
23d3c3
-            cp uuid duphash
23d3c3
-        else
23d3c3
-            echo "Cannot create neither 'duphas' nor 'uuid' because of missing 'backtrace' file"
23d3c3
-            exit 1
23d3c3
-        fi
23d3c3
         abrt-action-analyze-java -d $DUMP_DIR || exit 1
23d3c3
 
23d3c3
 # Create a bug in Bugzilla
23d3c3
diff --git a/test/outputs/not_reportable_1remote_class.log.in b/test/outputs/not_reportable_1remote_class.log.in
23d3c3
index 282933a..291072a 100644
23d3c3
--- a/test/outputs/not_reportable_1remote_class.log.in
23d3c3
+++ b/test/outputs/not_reportable_1remote_class.log.in
23d3c3
@@ -1 +1,6 @@
23d3c3
+duphash
23d3c3
+4bd13090ba6559c9c9023926671295559a25bc9b
23d3c3
+uuid
23d3c3
+4bd13090ba6559c9c9023926671295559a25bc9b
23d3c3
+not-reportable
23d3c3
 This problem can be caused by a 3rd party code from the jar/class at http://localhost:54321/JarTest.jar. In order to provide valuable problem reports, ABRT will not allow you to submit this problem. If you still want to participate in solving this problem, please contact the developers directly.
23d3c3
diff --git a/test/outputs/not_reportable_3remote_classes.log.in b/test/outputs/not_reportable_3remote_classes.log.in
23d3c3
index 7489f74..ddbd29c 100644
23d3c3
--- a/test/outputs/not_reportable_3remote_classes.log.in
23d3c3
+++ b/test/outputs/not_reportable_3remote_classes.log.in
23d3c3
@@ -1 +1,6 @@
23d3c3
+duphash
23d3c3
+4bd13090ba6559c9c9023926671295559a25bc9b
23d3c3
+uuid
23d3c3
+4bd13090ba6559c9c9023926671295559a25bc9b
23d3c3
+not-reportable
23d3c3
 This problem can be caused by a 3rd party code from the jar/class at http://localhost:54321/JarTest.jar, http://localhost:321/JarTest.jar, http://localhost:4321/JarTest.jar. In order to provide valuable problem reports, ABRT will not allow you to submit this problem. If you still want to participate in solving this problem, please contact the developers directly.
23d3c3
diff --git a/utils/abrt-action-analyze-java.c b/utils/abrt-action-analyze-java.c
23d3c3
index a4728b6..03542ec 100644
23d3c3
--- a/utils/abrt-action-analyze-java.c
23d3c3
+++ b/utils/abrt-action-analyze-java.c
23d3c3
@@ -17,6 +17,7 @@
23d3c3
 */
23d3c3
 
23d3c3
 #include <satyr/location.h>
23d3c3
+#include <satyr/thread.h>
23d3c3
 #include <satyr/java/stacktrace.h>
23d3c3
 #include <satyr/java/thread.h>
23d3c3
 #include <satyr/java/frame.h>
23d3c3
@@ -24,6 +25,16 @@
23d3c3
 #include <abrt/libabrt.h>
23d3c3
 #include <stdlib.h>
23d3c3
 
23d3c3
+/* 4 = 1 exception + 3 methods */
23d3c3
+#define FRAMES_FOR_DUPHASH 4
23d3c3
+
23d3c3
+typedef struct
23d3c3
+{
23d3c3
+    const char *name;
23d3c3
+    char *data;
23d3c3
+    int nofree;
23d3c3
+} analysis_result_t;
23d3c3
+
23d3c3
 static char *
23d3c3
 backtrace_from_dump_dir(const char *dir_name)
23d3c3
 {
23d3c3
@@ -44,37 +55,62 @@ backtrace_from_dump_dir(const char *dir_name)
23d3c3
 }
23d3c3
 
23d3c3
 static void
23d3c3
-write_not_reportable_message_to_dump_dir(const char *dir_name, const char *message)
23d3c3
+write_results_to_dump_dir(const char *dir_name,
23d3c3
+        const analysis_result_t *res_begin, const analysis_result_t *res_end)
23d3c3
 {
23d3c3
     struct dump_dir *dd = dd_opendir(dir_name, /*Open for writing*/0);
23d3c3
     if (NULL != dd)
23d3c3
     {
23d3c3
-        dd_save_text(dd, FILENAME_NOT_REPORTABLE, message);
23d3c3
+        const analysis_result_t *res = res_begin;
23d3c3
+
23d3c3
+        for ( ; res != res_end; ++res)
23d3c3
+            dd_save_text(dd, res->name, res->data);
23d3c3
+
23d3c3
         dd_close(dd);
23d3c3
     }
23d3c3
 }
23d3c3
 
23d3c3
 static void
23d3c3
-write_not_reportable_message_to_fd(int fdout, const char *message)
23d3c3
+write_to_fd(int fdout, const char *message)
23d3c3
 {
23d3c3
     full_write(fdout, message, strlen(message));
23d3c3
     full_write(fdout, "\n", 1);
23d3c3
 }
23d3c3
 
23d3c3
+
23d3c3
 static void
23d3c3
-write_not_reportable_message_to_file(const char *file_name, const char *message)
23d3c3
+write_results_to_fd(int fdout,
23d3c3
+        const analysis_result_t *res_begin, const analysis_result_t *res_end)
23d3c3
 {
23d3c3
-    int fdout = open(file_name,
23d3c3
-            O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW,
23d3c3
-            S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
23d3c3
+    const analysis_result_t *res = res_begin;
23d3c3
 
23d3c3
-    if (0 > fdout)
23d3c3
+    for ( ; res != res_end; ++res)
23d3c3
     {
23d3c3
-        perror_msg("Can't open file '%s' for writing", file_name);
23d3c3
-        return;
23d3c3
+        write_to_fd(fdout, res->name);
23d3c3
+        write_to_fd(fdout, res->data);
23d3c3
+    }
23d3c3
+}
23d3c3
+
23d3c3
+static void
23d3c3
+write_results_to_file(const analysis_result_t *res_begin, const analysis_result_t *res_end)
23d3c3
+{
23d3c3
+    const analysis_result_t *res = res_begin;
23d3c3
+
23d3c3
+    for ( ; res != res_end; ++res)
23d3c3
+    {
23d3c3
+        int fdout = open(res->name,
23d3c3
+                O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW,
23d3c3
+                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
23d3c3
+
23d3c3
+        if (0 > fdout)
23d3c3
+        {
23d3c3
+            perror_msg("Can't open file '%s' for writing", res->name);
23d3c3
+            continue;
23d3c3
+        }
23d3c3
+
23d3c3
+        write_to_fd(fdout, res->data);
23d3c3
+        close(fdout);
23d3c3
     }
23d3c3
-    write_not_reportable_message_to_fd(fdout, message);
23d3c3
-    close(fdout);
23d3c3
 }
23d3c3
 
23d3c3
 static char *
23d3c3
@@ -89,50 +125,46 @@ backtrace_from_file(const char *file_name)
23d3c3
     return xmalloc_xopen_read_close(file_name, /*no size limit*/NULL);
23d3c3
 }
23d3c3
 
23d3c3
-typedef void (*frame_cb)(struct sr_java_frame *frame, void *args);
23d3c3
-
23d3c3
-typedef struct {
23d3c3
-    frame_cb callback;
23d3c3
-    void *args;
23d3c3
-} frame_proc_t;
23d3c3
-
23d3c3
-static void
23d3c3
-iterate_trough_stacktrace(struct sr_java_stacktrace *stacktrace, frame_proc_t **fproc)
23d3c3
+static char *
23d3c3
+work_out_list_of_remote_urls(struct sr_java_stacktrace *stacktrace)
23d3c3
 {
23d3c3
+    struct strbuf *remote_files_csv = strbuf_new();
23d3c3
     struct sr_java_thread *thread = stacktrace->threads;
23d3c3
     while (NULL != thread)
23d3c3
     {
23d3c3
         struct sr_java_frame *frame = thread->frames;
23d3c3
         while (NULL != frame)
23d3c3
         {
23d3c3
-            frame_proc_t **it = fproc;
23d3c3
-            while (NULL != *it)
23d3c3
+            if (NULL != frame->class_path && prefixcmp(frame->class_path, "file://") != 0)
23d3c3
             {
23d3c3
-                (*it)->callback(frame, (*it)->args);
23d3c3
-                ++it;
23d3c3
+                struct stat buf;
23d3c3
+                if (stat(frame->class_path, &buf) && errno == ENOENT)
23d3c3
+                {
23d3c3
+                    if (strstr(remote_files_csv->buf, frame->class_path) == NULL)
23d3c3
+                    {
23d3c3
+                        log_debug("Adding a new path to the list of remote paths: '%s'", frame->class_path);
23d3c3
+                        strbuf_append_strf(remote_files_csv, "%s%s",
23d3c3
+                                remote_files_csv->buf[0] != '\0' ? ", " : "",
23d3c3
+                                frame->class_path);
23d3c3
+                    }
23d3c3
+                    else
23d3c3
+                        log_debug("The list of remote paths already contains path: '%s'", frame->class_path);
23d3c3
+                }
23d3c3
+                else
23d3c3
+                    log_debug("Class path exists or is malformed: '%s'", frame->class_path);
23d3c3
             }
23d3c3
             frame = frame->next;
23d3c3
         }
23d3c3
         thread = thread->next;
23d3c3
     }
23d3c3
-}
23d3c3
 
23d3c3
-static void
23d3c3
-work_out_list_of_remote_urls(struct sr_java_frame *frame, struct strbuf *remote_files_csv)
23d3c3
-{
23d3c3
-    if (NULL != frame->class_path && prefixcmp(frame->class_path, "file://") != 0)
23d3c3
+    if (remote_files_csv->buf[0] != '\0')
23d3c3
     {
23d3c3
-        struct stat buf;
23d3c3
-        if (stat(frame->class_path, &buf) && errno == ENOENT)
23d3c3
-        {
23d3c3
-            if (strstr(remote_files_csv->buf, frame->class_path) == NULL)
23d3c3
-            {
23d3c3
-                strbuf_append_strf(remote_files_csv, "%s%s",
23d3c3
-                        remote_files_csv->buf[0] != '\0' ? ", " : "",
23d3c3
-                        frame->class_path);
23d3c3
-            }
23d3c3
-        }
23d3c3
+        return strbuf_free_nobuf(remote_files_csv);
23d3c3
     }
23d3c3
+
23d3c3
+    strbuf_free(remote_files_csv);
23d3c3
+    return NULL;
23d3c3
 }
23d3c3
 
23d3c3
 int main(int argc, char *argv[])
23d3c3
@@ -153,7 +185,9 @@ int main(int argc, char *argv[])
23d3c3
     const char *program_usage_string = _(
23d3c3
         "& [[-d DIR] | [-f FILE]] [-o]\n"
23d3c3
         "\n"
23d3c3
-        "Analyzes Java backtrace\n"
23d3c3
+        "Analyzes Java backtrace, generates duplication hash and creates\n"
23d3c3
+        "not-reportable file for bracktraces whose frames have remote files in their\n"
23d3c3
+        "class path\n"
23d3c3
     );
23d3c3
     enum {
23d3c3
         OPT_v = 1 << 0,
23d3c3
@@ -208,49 +242,72 @@ int main(int argc, char *argv[])
23d3c3
         goto finish;
23d3c3
     }
23d3c3
 
23d3c3
-    struct strbuf *remote_files_csv = strbuf_new();
23d3c3
-    frame_proc_t remote_files_proc = {
23d3c3
-        .callback = (frame_cb)&work_out_list_of_remote_urls,
23d3c3
-        .args = (void *)remote_files_csv
23d3c3
-    };
23d3c3
+    analysis_result_t results[3] = { { 0 } };
23d3c3
+    analysis_result_t *results_iter = results;
23d3c3
 
23d3c3
-    frame_proc_t *fproc[] = {
23d3c3
-        &remote_files_proc,
23d3c3
-        //duphash_proc,
23d3c3
-        //backtrace_usability,
23d3c3
-        NULL,
23d3c3
-    };
23d3c3
+    char *remote_files_csv = work_out_list_of_remote_urls(stacktrace);
23d3c3
 
23d3c3
-    iterate_trough_stacktrace(stacktrace, fproc);
23d3c3
+    char *hash_str = NULL;
23d3c3
+    struct sr_thread *crash_thread = (struct sr_thread *)stacktrace->threads;
23d3c3
+    if (g_verbose >= 3)
23d3c3
+    {
23d3c3
+        hash_str = sr_thread_get_duphash(crash_thread, FRAMES_FOR_DUPHASH,
23d3c3
+                /*noprefix*/NULL, SR_DUPHASH_NOHASH);
23d3c3
+        log("Generating duphash from string: '%s'", hash_str);
23d3c3
+        free(hash_str);
23d3c3
+    }
23d3c3
+
23d3c3
+    hash_str = sr_thread_get_duphash(crash_thread, FRAMES_FOR_DUPHASH,
23d3c3
+            /*noprefix*/NULL, SR_DUPHASH_NORMAL);
23d3c3
+
23d3c3
+    /* DUPHASH is used for searching for duplicates in Bugzilla */
23d3c3
+    results_iter->name = FILENAME_DUPHASH;
23d3c3
+    results_iter->data = hash_str;
23d3c3
+    ++results_iter;
23d3c3
+
23d3c3
+    /* UUID is used for local deduplication */
23d3c3
+    results_iter->name = FILENAME_UUID;
23d3c3
+    results_iter->data = hash_str;
23d3c3
+    results_iter->nofree = 1;
23d3c3
+    ++results_iter;
23d3c3
 
23d3c3
     sr_java_stacktrace_free(stacktrace);
23d3c3
 
23d3c3
-    if ('\0' != remote_files_csv->buf[0])
23d3c3
+    if (NULL != remote_files_csv)
23d3c3
     {
23d3c3
-        char *not_reportable_message = xasprintf(
23d3c3
+        results_iter->name = FILENAME_NOT_REPORTABLE;
23d3c3
+        results_iter->data = xasprintf(
23d3c3
         _("This problem can be caused by a 3rd party code from the "\
23d3c3
         "jar/class at %s. In order to provide valuable problem " \
23d3c3
         "reports, ABRT will not allow you to submit this problem. If you " \
23d3c3
         "still want to participate in solving this problem, please contact " \
23d3c3
-        "the developers directly."), remote_files_csv->buf);
23d3c3
+        "the developers directly."), remote_files_csv);
23d3c3
+        ++results_iter;
23d3c3
+        free(remote_files_csv);
23d3c3
+    }
23d3c3
 
23d3c3
-        if (opts & OPT_o)
23d3c3
-        {
23d3c3
-            write_not_reportable_message_to_fd(STDOUT_FILENO,  not_reportable_message);
23d3c3
-        }
23d3c3
-        else if (NULL != dump_dir_name)
23d3c3
+    if (opts & OPT_o)
23d3c3
+    {
23d3c3
+        write_results_to_fd(STDOUT_FILENO, results, results_iter);
23d3c3
+    }
23d3c3
+    else if (NULL != dump_dir_name)
23d3c3
+    {
23d3c3
+        write_results_to_dump_dir(dump_dir_name, results, results_iter);
23d3c3
+    }
23d3c3
+    else
23d3c3
+    {   /* Just write it to the current working directory */
23d3c3
+        write_results_to_file(results, results_iter);
23d3c3
+    }
23d3c3
+
23d3c3
+    const analysis_result_t *res = results;
23d3c3
+    for (; res != results_iter; ++res)
23d3c3
+    {
23d3c3
+        if (!res->nofree)
23d3c3
         {
23d3c3
-            write_not_reportable_message_to_dump_dir(dump_dir_name,  not_reportable_message);
23d3c3
+            free(res->data);
23d3c3
         }
23d3c3
-        else
23d3c3
-        {   /* Just write it to the current working directory */
23d3c3
-            write_not_reportable_message_to_file(FILENAME_NOT_REPORTABLE,  not_reportable_message);
23d3c3
-        }
23d3c3
-
23d3c3
-        free(not_reportable_message);
23d3c3
     }
23d3c3
 
23d3c3
-    strbuf_free(remote_files_csv);
23d3c3
     retval = 0;
23d3c3
 finish:
23d3c3
 
23d3c3
-- 
23d3c3
1.8.3.1
23d3c3