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

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