|
|
b35d98 |
From ba1f3f10129765dec30caa238679331db6848938 Mon Sep 17 00:00:00 2001
|
|
|
b35d98 |
From: Jakub Filak <jfilak@redhat.com>
|
|
|
b35d98 |
Date: Wed, 15 Jan 2014 09:14:44 +0100
|
|
|
b35d98 |
Subject: [PATCH 22/39] Exception callback code optimizations
|
|
|
b35d98 |
|
|
|
b35d98 |
The old code was doing a lot of stuff which is not necessary when the
|
|
|
b35d98 |
processes exception won't be reported.
|
|
|
b35d98 |
|
|
|
b35d98 |
Related to rhbz#1051198
|
|
|
b35d98 |
---
|
|
|
b35d98 |
src/abrt-checker.c | 180 ++++++++++++++++++++++++++++++++---------------------
|
|
|
b35d98 |
1 file changed, 108 insertions(+), 72 deletions(-)
|
|
|
b35d98 |
|
|
|
b35d98 |
diff --git a/src/abrt-checker.c b/src/abrt-checker.c
|
|
|
b35d98 |
index 613a0ec..a5c2bdd 100644
|
|
|
b35d98 |
--- a/src/abrt-checker.c
|
|
|
b35d98 |
+++ b/src/abrt-checker.c
|
|
|
b35d98 |
@@ -219,6 +219,7 @@ T_jthreadMap *threadMap;
|
|
|
b35d98 |
static char* get_path_to_class(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jclass class, char *class_name, const char *stringize_method_name);
|
|
|
b35d98 |
static void print_jvm_environment_variables_to_file(FILE *out);
|
|
|
b35d98 |
static char* format_class_name(char *class_signature, char replace_to);
|
|
|
b35d98 |
+static int check_jvmti_error(jvmtiEnv *jvmti_env, jvmtiError error_code, const char *str);
|
|
|
b35d98 |
|
|
|
b35d98 |
|
|
|
b35d98 |
|
|
|
b35d98 |
@@ -404,26 +405,70 @@ static const char * null2empty(const char *str)
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
|
|
|
b35d98 |
+static char *get_exception_type_name(
|
|
|
b35d98 |
+ jvmtiEnv *jvmti_env,
|
|
|
b35d98 |
+ JNIEnv *jni_env,
|
|
|
b35d98 |
+ jobject exception_object)
|
|
|
b35d98 |
+{
|
|
|
b35d98 |
+ jclass exception_class = (*jni_env)->GetObjectClass(jni_env, exception_object);
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ char *exception_name_ptr = NULL;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ /* retrieve all required informations */
|
|
|
b35d98 |
+ jvmtiError error_code = (*jvmti_env)->GetClassSignature(jvmti_env, exception_class, &exception_name_ptr, NULL);
|
|
|
b35d98 |
+ if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
+ return NULL;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ char *formated_exception_name_ptr = format_class_name(exception_name_ptr, '\0');
|
|
|
b35d98 |
+ if (formated_exception_name_ptr != exception_name_ptr)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ char *dest = exception_name_ptr;
|
|
|
b35d98 |
+ char *src = formated_exception_name_ptr;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ while(src[0] != '\0')
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ *dest = *src;
|
|
|
b35d98 |
+ ++dest;
|
|
|
b35d98 |
+ ++src;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ dest[0] = '\0';
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ return exception_name_ptr;
|
|
|
b35d98 |
+}
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+
|
|
|
b35d98 |
|
|
|
b35d98 |
/*
|
|
|
b35d98 |
* Returns non zero value if exception's type is intended to be reported even
|
|
|
b35d98 |
* if the exception was caught.
|
|
|
b35d98 |
*/
|
|
|
b35d98 |
-static int exception_is_intended_to_be_reported(const char *type_name)
|
|
|
b35d98 |
+static int exception_is_intended_to_be_reported(
|
|
|
b35d98 |
+ jvmtiEnv *jvmti_env,
|
|
|
b35d98 |
+ JNIEnv *jni_env,
|
|
|
b35d98 |
+ jobject exception_object,
|
|
|
b35d98 |
+ char **exception_type)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
+ int retval = 0;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
if (reportedCaughExceptionTypes != NULL)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
+ *exception_type = get_exception_type_name(jvmti_env, jni_env, exception_object);
|
|
|
b35d98 |
+ if (NULL == *exception_type)
|
|
|
b35d98 |
+ return 0;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
/* special cases for selected exceptions */
|
|
|
b35d98 |
for (char **cursor = reportedCaughExceptionTypes; *cursor; ++cursor)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
- if (strcmp(*cursor, type_name) == 0)
|
|
|
b35d98 |
+ if (strcmp(*cursor, *exception_type) == 0)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
- return 1;
|
|
|
b35d98 |
+ retval = 1;
|
|
|
b35d98 |
+ break;
|
|
|
b35d98 |
}
|
|
|
b35d98 |
}
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
- return 0;
|
|
|
b35d98 |
+ return retval;
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
|
|
|
b35d98 |
@@ -695,19 +740,21 @@ static char* format_class_name(char *class_signature, char replace_to)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
output++; /* goto to the next character */
|
|
|
b35d98 |
}
|
|
|
b35d98 |
- /* replace the last character in the class name */
|
|
|
b35d98 |
- /* but inly if this character is ';' */
|
|
|
b35d98 |
- char *last_char = output + strlen(output) - 1;
|
|
|
b35d98 |
- if (*last_char == ';')
|
|
|
b35d98 |
- {
|
|
|
b35d98 |
- *last_char = replace_to;
|
|
|
b35d98 |
- }
|
|
|
b35d98 |
+
|
|
|
b35d98 |
/* replace all '/'s to '.'s */
|
|
|
b35d98 |
char *c;
|
|
|
b35d98 |
for (c = class_signature; *c != 0; c++)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
if (*c == '/') *c = '.';
|
|
|
b35d98 |
}
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ /* replace the last character in the class name */
|
|
|
b35d98 |
+ /* but inly if this character is ';' */
|
|
|
b35d98 |
+ /* c[0] == '\0' see the for loop above */
|
|
|
b35d98 |
+ if (c != class_signature && c[-1] == ';')
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ c[-1] = replace_to;
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
}
|
|
|
b35d98 |
else
|
|
|
b35d98 |
{
|
|
|
b35d98 |
@@ -2053,52 +2100,17 @@ static void JNICALL callback_on_exception(
|
|
|
b35d98 |
jmethodID catch_method,
|
|
|
b35d98 |
jlocation catch_location __UNUSED_VAR)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
- jvmtiError error_code;
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- char *method_name_ptr = NULL;
|
|
|
b35d98 |
- char *method_signature_ptr = NULL;
|
|
|
b35d98 |
- char *class_name_ptr = NULL;
|
|
|
b35d98 |
- char *class_signature_ptr = NULL;
|
|
|
b35d98 |
- char *exception_name_ptr = NULL;
|
|
|
b35d98 |
- char *updated_exception_name_ptr = NULL;
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- jclass method_class;
|
|
|
b35d98 |
- jclass exception_class;
|
|
|
b35d98 |
+ char *exception_type_name = NULL;
|
|
|
b35d98 |
|
|
|
b35d98 |
/* all operations should be processed in critical section */
|
|
|
b35d98 |
enter_critical_section(jvmti_env, shared_lock);
|
|
|
b35d98 |
|
|
|
b35d98 |
- char tname[MAX_THREAD_NAME_LENGTH];
|
|
|
b35d98 |
- get_thread_name(jvmti_env, thr, tname, sizeof(tname));
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- exception_class = (*jni_env)->GetObjectClass(jni_env, exception_object);
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- /* retrieve all required informations */
|
|
|
b35d98 |
- error_code = (*jvmti_env)->GetMethodName(jvmti_env, method, &method_name_ptr, &method_signature_ptr, NULL);
|
|
|
b35d98 |
- if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
- goto callback_on_exception_cleanup;
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- error_code = (*jvmti_env)->GetMethodDeclaringClass(jvmti_env, method, &method_class);
|
|
|
b35d98 |
- if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
- goto callback_on_exception_cleanup;
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- error_code = (*jvmti_env)->GetClassSignature(jvmti_env, method_class, &class_signature_ptr, NULL);
|
|
|
b35d98 |
- if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
- goto callback_on_exception_cleanup;
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- error_code = (*jvmti_env)->GetClassSignature(jvmti_env, exception_class, &exception_name_ptr, NULL);
|
|
|
b35d98 |
- if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
- goto callback_on_exception_cleanup;
|
|
|
b35d98 |
-
|
|
|
b35d98 |
/* readable class names */
|
|
|
b35d98 |
- class_name_ptr = format_class_name(class_signature_ptr, '.');
|
|
|
b35d98 |
- updated_exception_name_ptr = format_class_name(exception_name_ptr, '\0');
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- INFO_PRINT("%s %s exception in thread \"%s\" ", (catch_method == NULL ? "Uncaught" : "Caught"), updated_exception_name_ptr, tname);
|
|
|
b35d98 |
- INFO_PRINT("in a method %s%s() with signature %s\n", class_name_ptr, method_name_ptr, method_signature_ptr);
|
|
|
b35d98 |
-
|
|
|
b35d98 |
- if (catch_method == NULL || exception_is_intended_to_be_reported(updated_exception_name_ptr))
|
|
|
b35d98 |
+ if (catch_method == NULL || exception_is_intended_to_be_reported(jvmti_env, jni_env, exception_object, &exception_type_name))
|
|
|
b35d98 |
{
|
|
|
b35d98 |
+ char tname[MAX_THREAD_NAME_LENGTH];
|
|
|
b35d98 |
+ get_thread_name(jvmti_env, thr, tname, sizeof(tname));
|
|
|
b35d98 |
+
|
|
|
b35d98 |
jlong tid = 0;
|
|
|
b35d98 |
T_jthrowableCircularBuf *threads_exc_buf = NULL;
|
|
|
b35d98 |
|
|
|
b35d98 |
@@ -2114,19 +2126,43 @@ static void JNICALL callback_on_exception(
|
|
|
b35d98 |
|
|
|
b35d98 |
if (NULL == threads_exc_buf || NULL == jthrowable_circular_buf_find(threads_exc_buf, exception_object))
|
|
|
b35d98 |
{
|
|
|
b35d98 |
+ jvmtiError error_code;
|
|
|
b35d98 |
+ jclass method_class;
|
|
|
b35d98 |
+ char *method_name_ptr = NULL;
|
|
|
b35d98 |
+ char *method_signature_ptr = NULL;
|
|
|
b35d98 |
+ char *class_name_ptr = NULL;
|
|
|
b35d98 |
+ char *class_signature_ptr = NULL;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
if (NULL != threads_exc_buf)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
VERBOSE_PRINT("Pushing to circular buffer\n");
|
|
|
b35d98 |
jthrowable_circular_buf_push(threads_exc_buf, exception_object);
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
+ error_code = (*jvmti_env)->GetMethodName(jvmti_env, method, &method_name_ptr, &method_signature_ptr, NULL);
|
|
|
b35d98 |
+ if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
+ goto callback_on_exception_cleanup;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ error_code = (*jvmti_env)->GetMethodDeclaringClass(jvmti_env, method, &method_class);
|
|
|
b35d98 |
+ if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
+ goto callback_on_exception_cleanup;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ error_code = (*jvmti_env)->GetClassSignature(jvmti_env, method_class, &class_signature_ptr, NULL);
|
|
|
b35d98 |
+ if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
|
|
|
b35d98 |
+ goto callback_on_exception_cleanup;
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+ class_name_ptr = format_class_name(class_signature_ptr, '.');
|
|
|
b35d98 |
+
|
|
|
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 |
+ if (NULL == exception_type_name)
|
|
|
b35d98 |
+ exception_type_name = get_exception_type_name(jvmti_env, jni_env, exception_object);
|
|
|
b35d98 |
+
|
|
|
b35d98 |
char *message = format_exception_reason_message(/*caught?*/NULL != catch_method,
|
|
|
b35d98 |
- updated_exception_name_ptr, class_name_ptr, method_name_ptr);
|
|
|
b35d98 |
+ exception_type_name, class_name_ptr, method_name_ptr);
|
|
|
b35d98 |
|
|
|
b35d98 |
char *executable = NULL;
|
|
|
b35d98 |
char *stack_trace_str = generate_thread_stack_trace(jvmti_env, jni_env, tname, exception_object,
|
|
|
b35d98 |
@@ -2143,6 +2179,24 @@ static void JNICALL callback_on_exception(
|
|
|
b35d98 |
|
|
|
b35d98 |
free(message);
|
|
|
b35d98 |
free(stack_trace_str);
|
|
|
b35d98 |
+
|
|
|
b35d98 |
+callback_on_exception_cleanup:
|
|
|
b35d98 |
+ /* cleapup */
|
|
|
b35d98 |
+ if (method_name_ptr != NULL)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)method_name_ptr);
|
|
|
b35d98 |
+ check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ if (method_signature_ptr != NULL)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)method_signature_ptr);
|
|
|
b35d98 |
+ check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
+ if (class_signature_ptr != NULL)
|
|
|
b35d98 |
+ {
|
|
|
b35d98 |
+ error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)class_signature_ptr);
|
|
|
b35d98 |
+ check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
+ }
|
|
|
b35d98 |
}
|
|
|
b35d98 |
else
|
|
|
b35d98 |
{
|
|
|
b35d98 |
@@ -2150,27 +2204,9 @@ static void JNICALL callback_on_exception(
|
|
|
b35d98 |
}
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
-callback_on_exception_cleanup:
|
|
|
b35d98 |
- /* cleapup */
|
|
|
b35d98 |
- if (method_name_ptr != NULL)
|
|
|
b35d98 |
- {
|
|
|
b35d98 |
- error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)method_name_ptr);
|
|
|
b35d98 |
- check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
- }
|
|
|
b35d98 |
- if (method_signature_ptr != NULL)
|
|
|
b35d98 |
+ if (NULL != exception_type_name)
|
|
|
b35d98 |
{
|
|
|
b35d98 |
- error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)method_signature_ptr);
|
|
|
b35d98 |
- check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
- }
|
|
|
b35d98 |
- if (class_signature_ptr != NULL)
|
|
|
b35d98 |
- {
|
|
|
b35d98 |
- error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)class_signature_ptr);
|
|
|
b35d98 |
- check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
- }
|
|
|
b35d98 |
- if (exception_name_ptr != NULL)
|
|
|
b35d98 |
- {
|
|
|
b35d98 |
- error_code = (*jvmti_env)->Deallocate(jvmti_env, (unsigned char *)exception_name_ptr);
|
|
|
b35d98 |
- check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__));
|
|
|
b35d98 |
+ free(exception_type_name);
|
|
|
b35d98 |
}
|
|
|
b35d98 |
|
|
|
b35d98 |
exit_critical_section(jvmti_env, shared_lock);
|
|
|
b35d98 |
--
|
|
|
b35d98 |
1.8.3.1
|
|
|
b35d98 |
|