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

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