|
|
b35d98 |
From 9eaeea7851ff8682b7b6289dd9bded87d29c6fdd Mon Sep 17 00:00:00 2001
|
|
|
b35d98 |
From: Jakub Filak <jfilak@redhat.com>
|
|
|
b35d98 |
Date: Fri, 25 Oct 2013 15:46:43 +0200
|
|
|
b35d98 |
Subject: [PATCH 05/39] Unify reason message format
|
|
|
b35d98 |
|
|
|
b35d98 |
Use the same message for abrt and log:
|
|
|
b35d98 |
|
|
|
b35d98 |
(Caught|Uncaght) exception $FQDN_TYPE in method $FQDN_METHOD
|
|
|
b35d98 |
|
|
|
b35d98 |
The new format misses thread name and method signature. Thread's name is
|
|
|
b35d98 |
available in stack trace and method's signature is useful only for
|
|
|
b35d98 |
debugging.
|
|
|
b35d98 |
|
|
|
b35d98 |
Length of the reason message is limited to 255 characters. If the
|
|
|
b35d98 |
message exceeds that limit, algorithm tries to generate the message
|
|
|
b35d98 |
according to the following formats:
|
|
|
b35d98 |
|
|
|
b35d98 |
(Caught|Uncaght) exception $FQDN_TYPE in method $CLASS_NAME_METHOD
|
|
|
b35d98 |
(Caught|Uncaght) exception $EXCEPTION_CLASS in method $CLASS_NAME_METHOD
|
|
|
b35d98 |
(Caught|Uncaght) exception $EXCEPTION_CLASS in method $METHOD
|
|
|
b35d98 |
|
|
|
b35d98 |
The first suitable message is used. If none of these formats generate an
|
|
|
b35d98 |
acceptable message, the last format is used and the message is truncated.
|
|
|
b35d98 |
|
|
|
b35d98 |
Related to rhbz#1023081
|
|
|
b35d98 |
Related to rhbz#1055581
|
|
|
b35d98 |
|
|
|
b35d98 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
|
b35d98 |
---
|
|
|
b35d98 |
src/abrt-checker.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++--------
|
|
|
b35d98 |
1 file changed, 85 insertions(+), 14 deletions(-)
|
|
|
b35d98 |
|
|
|
b35d98 |
diff --git a/src/abrt-checker.c b/src/abrt-checker.c
|
|
|
b35d98 |
index 22f772e..23e76b0 100644
|
|
|
b35d98 |
--- a/src/abrt-checker.c
|
|
|
b35d98 |
+++ b/src/abrt-checker.c
|
|
|
b35d98 |
@@ -87,6 +87,9 @@
|
|
|
b35d98 |
/* Don't need to be changed */
|
|
|
b35d98 |
#define MAX_THREAD_NAME_LENGTH 40
|
|
|
b35d98 |
|
|
|
b35d98 |
+/* Max. length of reason message */
|
|
|
b35d98 |
+#define MAX_REASON_MESSAGE_STRING_LENGTH 255
|
|
|
b35d98 |
+
|
|
|
b35d98 |
/* Max. length of stack trace */
|
|
|
b35d98 |
#define MAX_STACK_TRACE_STRING_LENGTH 10000
|
|
|
b35d98 |
|
|
|
b35d98 |
@@ -402,7 +405,7 @@ static void add_process_properties_data(problem_data_t *pd)
|
|
|
b35d98 |
* Register new ABRT event using given message and a method name.
|
|
|
b35d98 |
* If reportErrosTo global flags doesn't contain ED_ABRT, this function does nothing.
|
|
|
b35d98 |
*/
|
|
|
b35d98 |
-static void register_abrt_event(char * executable, char * message, unsigned char * method, char * backtrace)
|
|
|
b35d98 |
+static void register_abrt_event(char * executable, char * message, char * backtrace)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
if ((reportErrosTo & ED_ABRT) == 0)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
@@ -410,7 +413,6 @@ static void register_abrt_event(char * executable, char * message, unsigned char
|
|
|
b35d98 |
return;
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
- char abrt_message[1000];
|
|
|
b35d98 |
char s[11];
|
|
|
b35d98 |
problem_data_t *pd = problem_data_new();
|
|
|
b35d98 |
|
|
|
b35d98 |
@@ -421,14 +423,12 @@ static void register_abrt_event(char * executable, char * message, unsigned char
|
|
|
b35d98 |
get_uid_as_string(s);
|
|
|
b35d98 |
problem_data_add_text_editable(pd, FILENAME_UID, s);
|
|
|
b35d98 |
|
|
|
b35d98 |
- sprintf(abrt_message, "%s in method %s", message, method);
|
|
|
b35d98 |
-
|
|
|
b35d98 |
/* executable must belong to some package otherwise ABRT refuse it */
|
|
|
b35d98 |
problem_data_add_text_editable(pd, FILENAME_EXECUTABLE, executable);
|
|
|
b35d98 |
problem_data_add_text_editable(pd, FILENAME_BACKTRACE, backtrace);
|
|
|
b35d98 |
|
|
|
b35d98 |
/* type and analyzer are the same for abrt, we keep both just for sake of comaptibility */
|
|
|
b35d98 |
- problem_data_add_text_editable(pd, FILENAME_REASON, abrt_message);
|
|
|
b35d98 |
+ problem_data_add_text_editable(pd, FILENAME_REASON, message);
|
|
|
b35d98 |
/* end of required fields */
|
|
|
b35d98 |
|
|
|
b35d98 |
/* add optional fields */
|
|
|
b35d98 |
@@ -489,6 +489,66 @@ static int get_tid(
|
|
|
b35d98 |
|
|
|
b35d98 |
|
|
|
b35d98 |
|
|
|
b35d98 |
+static char *format_exception_reason_message(
|
|
|
b35d98 |
+ int caught,
|
|
|
b35d98 |
+ const char *exception_fqdn,
|
|
|
b35d98 |
+ const char *class_fqdn,
|
|
|
b35d98 |
+ const char *method)
|
|
|
b35d98 |
+{
|
|
|
b35d98 |
+ const char *exception_name = exception_fqdn;
|
|
|
b35d98 |
+ const char *class_name = class_fqdn;
|
|
|
b35d98 |
+ const char *prefix = caught ? "Caught" : "Uncaught";
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ char *message = (char*)calloc(MAX_REASON_MESSAGE_STRING_LENGTH + 1, sizeof(char));
|
|
|
b35d98 |
+ if (message == NULL)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ fprintf(stderr, __FILE__ ":" STRINGIZE(__LINE__) ": calloc(): out of memory");
|
|
|
b35d98 |
+ return NULL;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ while (1)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ const int message_len = snprintf(message, MAX_REASON_MESSAGE_STRING_LENGTH,
|
|
|
b35d98 |
+ "%s exception %s in method %s%s%s()", prefix,
|
|
|
b35d98 |
+ exception_name, class_name, ('\0' != class_name[0] ? "." : ""),
|
|
|
b35d98 |
+ method);
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ if (message_len <= 0)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ fprintf(stderr, __FILE__ ":" STRINGIZE(__LINE__) ": snprintf(): can't print reason message to memory on stack\n");
|
|
|
b35d98 |
+ free(message);
|
|
|
b35d98 |
+ return NULL;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ else if (message_len >= MAX_REASON_MESSAGE_STRING_LENGTH)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ const char *ptr = NULL;
|
|
|
b35d98 |
+ if (NULL != (ptr = strrchr(class_name, '.')))
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ /* Drop name space from method signature */
|
|
|
b35d98 |
+ class_name = ptr + 1;
|
|
|
b35d98 |
+ continue;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ else if(NULL != (ptr = strrchr(exception_name, '.')))
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ /* Drop name space from exception class signature */
|
|
|
b35d98 |
+ exception_name = ptr + 1;
|
|
|
b35d98 |
+ continue;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ else if (class_name[0] != '\0')
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ /* Drop class name from method signature */
|
|
|
b35d98 |
+ class_name += strlen(class_name);
|
|
|
b35d98 |
+ continue;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ /* No more place for shortening. The message will remain truncated. */
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ return message;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+}
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+
|
|
|
b35d98 |
/*
|
|
|
b35d98 |
* Format class signature into a printable form.
|
|
|
b35d98 |
* Class names have form "Ljava/lang/String;"
|
|
|
b35d98 |
@@ -1892,19 +1952,30 @@ static void JNICALL callback_on_exception(
|
|
|
b35d98 |
jthrowable_circular_buf_push(threads_exc_buf, exception_object);
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
- log_print("%s %s exception in thread \"%s\" ", (catch_method == NULL ? "Uncaught" : "Caught"), updated_exception_name_ptr, tname);
|
|
|
b35d98 |
- log_print("in a method %s%s() with signature %s\n", class_name_ptr, method_name_ptr, method_signature_ptr);
|
|
|
b35d98 |
+ /* Remove trailing '.' */
|
|
|
b35d98 |
+ const ssize_t class_name_len = strlen(class_name_ptr);
|
|
|
b35d98 |
+ if (class_name_len > 0)
|
|
|
b35d98 |
+ class_name_ptr[class_name_len - 1] = '\0';
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ char *message = format_exception_reason_message(/*caught?*/NULL != catch_method,
|
|
|
b35d98 |
+ updated_exception_name_ptr, class_name_ptr, method_name_ptr);
|
|
|
b35d98 |
|
|
|
b35d98 |
- //char *stack_trace_str = generate_stack_trace(jvmti_env, jni_env, thr, tname, updated_exception_name_ptr);
|
|
|
b35d98 |
- char *stack_trace_str = generate_thread_stack_trace(jvmti_env, jni_env, tname, exception_object);
|
|
|
b35d98 |
- if (NULL != stack_trace_str)
|
|
|
b35d98 |
+ if (NULL != message)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
- log_print("%s", stack_trace_str);
|
|
|
b35d98 |
- if (NULL != threads_exc_buf)
|
|
|
b35d98 |
+ log_print("%s\n", message);
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ //char *stack_trace_str = generate_stack_trace(jvmti_env, jni_env, thr, tname, updated_exception_name_ptr);
|
|
|
b35d98 |
+ char *stack_trace_str = generate_thread_stack_trace(jvmti_env, jni_env, tname, exception_object);
|
|
|
b35d98 |
+ if (NULL != stack_trace_str)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
- register_abrt_event(processProperties.main_class, (catch_method == NULL ? "Uncaught exception" : "Caught exception"), (unsigned char *)method_name_ptr, stack_trace_str);
|
|
|
b35d98 |
+ log_print("%s", stack_trace_str);
|
|
|
b35d98 |
+ if (NULL != threads_exc_buf)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ register_abrt_event(processProperties.main_class, message, stack_trace_str);
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ free(stack_trace_str);
|
|
|
b35d98 |
}
|
|
|
b35d98 |
- free(stack_trace_str);
|
|
|
b35d98 |
+ free(message);
|
|
|
b35d98 |
}
|
|
|
b35d98 |
}
|
|
|
b35d98 |
else
|
|
|
b35d98 |
--
|
|
|
b35d98 |
1.8.3.1
|
|
|
b35d98 |
|