|
|
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 |
|