From a174f452fc48735da7ee49ab5c906528f87b77b5 Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Thu, 9 Jan 2014 22:56:28 +0100
Subject: [PATCH 26/39] Surround all JNI calls in try catch all block
Related to rhbz#1051198
---
src/abrt-checker.c | 273 ++++++++++++++++++------------------------
src/jthrowable_circular_buf.c | 40 ++++++-
2 files changed, 155 insertions(+), 158 deletions(-)
diff --git a/src/abrt-checker.c b/src/abrt-checker.c
index fb0c0eb..b6f11e8 100644
--- a/src/abrt-checker.c
+++ b/src/abrt-checker.c
@@ -631,6 +631,26 @@ static void report_stacktrace(
/*
+ * Returns logical true if exception occurred and clears it.
+ */
+static inline int check_and_clear_exception(
+ JNIEnv *jni_env)
+{
+ if ((*jni_env)->ExceptionOccurred(jni_env))
+ {
+#ifdef VERBOSE
+ (*jni_env)->ExceptionDescribe(jni_env);
+#endif
+ (*jni_env)->ExceptionClear(jni_env);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+/*
* Print a message when any JVM TI error occurs.
*/
static void print_jvmti_error(
@@ -666,12 +686,13 @@ static int get_tid(
}
jmethodID get_id = (*jni_env)->GetMethodID(jni_env, thread_class, "getId", "()J" );
- if (NULL == get_id)
+ if (check_and_clear_exception(jni_env) || NULL == get_id)
{
- VERBOSE_PRINT("Cannot method java.lang.Thread.getId()J\n");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of java/lang/Thread.getId()J\n");
return 1;
}
+ /* Thread.getId() throws nothing */
*tid = (*jni_env)->CallLongMethod(jni_env, thr, get_id);
return 0;
@@ -908,7 +929,6 @@ static void get_thread_name(
}
-
/*
* Read executable name from link /proc/${PID}/exe
*/
@@ -1068,7 +1088,7 @@ static char *get_main_class(
char *class_name;
error_code = (*jvmti_env)->GetSystemProperty(jvmti_env, "sun.java.command", &class_name);
- if (error_code != JVMTI_ERROR_NONE)
+ if (error_code != JVMTI_ERROR_NONE || NULL == class_name)
{
return UNKNOWN_CLASS_NAME;
}
@@ -1081,26 +1101,10 @@ static char *get_main_class(
string_replace(class_name, '.', '/');
jclass cls = (*jni_env)->FindClass(jni_env, class_name);
- /* Throws:
- * ClassFormatError: if the class data does not specify a valid class.
- * ClassCircularityError: if a class or interface would be its own superclass or superinterface.
- * NoClassDefFoundError: if no definition for a requested class or interface can be found.
- * OutOfMemoryError: if the system runs out of memory.
- */
-
- jthrowable exception;
- exception = (*jni_env)->ExceptionOccurred(jni_env);
- if (exception)
+ if (check_and_clear_exception(jni_env) || cls == NULL)
{
- (*jni_env)->ExceptionClear(jni_env);
- }
-
- if (cls == NULL)
- {
- if (class_name != NULL)
- {
- (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)class_name);
- }
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class of %s\n", class_name);
+ (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)class_name);
return UNKNOWN_CLASS_NAME;
}
@@ -1428,6 +1432,7 @@ static char* get_path_to_class_class_loader(
char *class_name,
const char *stringize_method_name)
{
+ char *out = NULL;
jclass class_loader_class = NULL;
char *upd_class_name = (char*)malloc(strlen(class_name) + sizeof("class") + 1);
@@ -1442,47 +1447,18 @@ static char* get_path_to_class_class_loader(
/* find ClassLoader class */
class_loader_class = (*jni_env)->FindClass(jni_env, "java/lang/ClassLoader");
- /* Throws:
- * ClassFormatError: if the class data does not specify a valid class.
- * ClassCircularityError: if a class or interface would be its own superclass or superinterface.
- * NoClassDefFoundError: if no definition for a requested class or interface can be found.
- * OutOfMemoryError: if the system runs out of memory.
- */
-
- /* check if exception was thrown from FindClass() method */
- jthrowable exception;
- exception = (*jni_env)->ExceptionOccurred(jni_env);
- if (exception)
- {
- (*jni_env)->ExceptionClear(jni_env);
- free(upd_class_name);
- return NULL;
- }
-
- if (class_loader_class == NULL)
+ if (check_and_clear_exception(jni_env) || class_loader_class == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class of java/lang/ClassLoader\n");
free(upd_class_name);
return NULL;
}
/* find method ClassLoader.getResource() */
- jmethodID get_resource = (*jni_env)->GetMethodID(jni_env, class_loader_class, "getResource", "(Ljava/lang/String;)Ljava/net/URL;" );
- /* Throws:
- * NoSuchMethodError: if the specified method cannot be found.
- * ExceptionInInitializerError: if the class initializer fails due to an exception.
- * OutOfMemoryError: if the system runs out of memory.
- */
-
- exception = (*jni_env)->ExceptionOccurred(jni_env);
- if (exception)
- {
- free(upd_class_name);
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- return NULL;
- }
-
- if (get_resource == NULL)
+ jmethodID get_resource = (*jni_env)->GetMethodID(jni_env, class_loader_class, "getResource", "(Ljava/lang/String;)Ljava/net/URL;");
+ if (check_and_clear_exception(jni_env) || get_resource == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of java/lang/ClassLoader.getResource(Ljava/lang/String;)Ljava/net/URL;\n");
free(upd_class_name);
(*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
return NULL;
@@ -1491,52 +1467,46 @@ static char* get_path_to_class_class_loader(
/* convert new class name into a Java String */
jstring j_class_name = (*jni_env)->NewStringUTF(jni_env, upd_class_name);
free(upd_class_name);
+ if (check_and_clear_exception(jni_env))
+ {
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not allocate a new UTF string for '%s'\n", upd_class_name);
+ goto get_path_to_class_class_loader_lcl_refs_cleanup;
+ }
/* call method ClassLoader.getResource(className) */
jobject url = (*jni_env)->CallObjectMethod(jni_env, class_loader, get_resource, j_class_name);
- if ((*jni_env)->ExceptionCheck(jni_env))
+ if (check_and_clear_exception(jni_env) || NULL == url)
{
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- (*jni_env)->DeleteLocalRef(jni_env, j_class_name);
- (*jni_env)->ExceptionClear(jni_env);
- return NULL;
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get a resource of %s\n", class_name);
+ goto get_path_to_class_class_loader_lcl_refs_cleanup;
}
- if (url == NULL)
+
+ /* find method URL.toString() */
+ jclass url_class = (*jni_env)->FindClass(jni_env, "java/net/URL");
+ if (check_and_clear_exception(jni_env) || NULL == url_class)
{
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- (*jni_env)->DeleteLocalRef(jni_env, j_class_name);
- return NULL;
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class of java/net/URL\n");
+ goto get_path_to_class_class_loader_lcl_refs_cleanup;
}
- /* find method URL.toString() */
- jmethodID to_external_form = (*jni_env)->GetMethodID(jni_env, (*jni_env)->FindClass(jni_env, "java/net/URL"), stringize_method_name, "()Ljava/lang/String;" );
- /* Throws:
- * NoSuchMethodError: if the specified method cannot be found.
- * ExceptionInInitializerError: if the class initializer fails due to an exception.
- * OutOfMemoryError: if the system runs out of memory.
- */
- exception = (*jni_env)->ExceptionOccurred(jni_env);
- if (exception)
+ jmethodID to_external_form = (*jni_env)->GetMethodID(jni_env, url_class, stringize_method_name, "()Ljava/lang/String;");
+ if (check_and_clear_exception(jni_env) || NULL == to_external_form)
{
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- (*jni_env)->DeleteLocalRef(jni_env, j_class_name);
- return NULL;
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of java/net/URL.%s()Ljava/lang/String;\n", stringize_method_name);
+ goto get_path_to_class_class_loader_lcl_refs_cleanup;
}
/* call method URL.toString() */
jstring jstr = (jstring)(*jni_env)->CallObjectMethod(jni_env, url, to_external_form);
- /* no exception expected */
-
- if (jstr == NULL)
+ if (check_and_clear_exception(jni_env) || jstr == NULL)
{
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- (*jni_env)->DeleteLocalRef(jni_env, j_class_name);
- return NULL;
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Failed to convert an URL object to a string\n");
+ goto get_path_to_class_class_loader_lcl_refs_cleanup;
}
/* convert Java String into C char* */
char *str = (char*)(*jni_env)->GetStringUTFChars(jni_env, jstr, NULL);
- char *out = strdup(str);
+ out = strdup(str);
if (out == NULL)
{
fprintf(stderr, "strdup(): out of memory");
@@ -1544,6 +1514,8 @@ static char* get_path_to_class_class_loader(
/* cleanup */
(*jni_env)->ReleaseStringUTFChars(jni_env, jstr, str);
+
+get_path_to_class_class_loader_lcl_refs_cleanup:
(*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
(*jni_env)->DeleteLocalRef(jni_env, j_class_name);
return out;
@@ -1558,39 +1530,30 @@ static jobject get_system_class_loader(
jvmtiEnv *jvmti_env __UNUSED_VAR,
JNIEnv *jni_env)
{
+ jobject system_class_loader = NULL;
+
jclass class_loader_class = (*jni_env)->FindClass(jni_env, "java/lang/ClassLoader");
- if (NULL == class_loader_class)
+ if (check_and_clear_exception(jni_env) || NULL == class_loader_class)
{
- VERBOSE_PRINT("Cannot find java/lang/ClassLoader class\n");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class of java/lang/ClassLoader\n");
return NULL;
}
jmethodID get_system_class_loader_smethod =(*jni_env)->GetStaticMethodID(jni_env, class_loader_class, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
- jthrowable exception = (*jni_env)->ExceptionOccurred(jni_env);
- if (NULL != exception)
- {
- VERBOSE_PRINT("Exception occured: can not get method java.lang.ClassLoader.getSystemClassLoader()\n");
- (*jni_env)->ExceptionClear(jni_env);
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- return NULL;
- }
- if (NULL == get_system_class_loader_smethod)
+ if (check_and_clear_exception(jni_env) || NULL == get_system_class_loader_smethod)
{
- VERBOSE_PRINT("Cannot find java.lang.ClassLoader.getSystemClassLoader()Ljava/lang/ClassLoader;\n");
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- return NULL;
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not find method java.lang.ClassLoader.getSystemClassLoader()Ljava/lang/ClassLoader;\n");
+ goto get_system_class_loader_cleanup;
}
- jobject system_class_loader = (*jni_env)->CallStaticObjectMethod(jni_env, class_loader_class, get_system_class_loader_smethod);
- exception = (*jni_env)->ExceptionOccurred(jni_env);
- if (NULL != exception)
+ system_class_loader = (*jni_env)->CallStaticObjectMethod(jni_env, class_loader_class, get_system_class_loader_smethod);
+ if (check_and_clear_exception(jni_env))
{
- VERBOSE_PRINT("java.lang.ClassLoader.getSystemClassLoader() thrown an exception\n");
- (*jni_env)->ExceptionClear(jni_env);
- (*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
- return NULL;
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Exception occurred: Cannot get the system class loader\n");
+ goto get_system_class_loader_cleanup;
}
+get_system_class_loader_cleanup:
(*jni_env)->DeleteLocalRef(jni_env, class_loader_class);
return system_class_loader;
}
@@ -1613,12 +1576,12 @@ static char* get_path_to_class(
/* class is loaded using boot classloader */
if (class_loader == NULL)
{
- VERBOSE_PRINT("A class has not been loaded by a ClassLoader. Going to use the system class loader.\n");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": A class has not been loaded by a ClassLoader. Going to use the system class loader.\n");
class_loader = get_system_class_loader(jvmti_env, jni_env);
if (NULL == class_loader)
{
- VERBOSE_PRINT("Cannot get the system class loader.");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Cannot get the system class loader.");
return NULL;
}
}
@@ -1642,16 +1605,16 @@ static jclass find_class_in_loaded_class(
}
jclass class_class = (*jni_env)->FindClass(jni_env, "java/lang/Class");
- if (NULL == class_class)
+ if (check_and_clear_exception(jni_env) || NULL == class_class)
{
- VERBOSE_PRINT("Cannot find java/lang/Class class");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class of java/lang/Class\n");
goto find_class_in_loaded_class_cleanup;
}
jmethodID get_name_method = (*jni_env)->GetMethodID(jni_env, class_class, "getName", "()Ljava/lang/String;");
- if (NULL == get_name_method)
+ if (check_and_clear_exception(jni_env) || NULL == get_name_method)
{
- VERBOSE_PRINT("Cannot find java.lang.Class.getName.()Ljava/lang/String;");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of java/lang/Class.getName()Ljava/lang/String;\n");
(*jni_env)->DeleteLocalRef(jni_env, class_class);
goto find_class_in_loaded_class_cleanup;
}
@@ -1659,8 +1622,9 @@ static jclass find_class_in_loaded_class(
for (jint i = 0; NULL == result && i < num_classes; ++i)
{
jobject class_name = (*jni_env)->CallObjectMethod(jni_env, loaded_classes[i], get_name_method);
- if (NULL == class_name)
+ if (check_and_clear_exception(jni_env) || NULL == class_name)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get name of a loaded class\n");
continue;
}
@@ -1697,21 +1661,17 @@ static int print_stack_trace_element(
{
jclass stack_frame_class = (*jni_env)->GetObjectClass(jni_env, stack_frame);
jmethodID get_class_name_method = (*jni_env)->GetMethodID(jni_env, stack_frame_class, "getClassName", "()Ljava/lang/String;");
- if (get_class_name_method == NULL)
+ if (check_and_clear_exception(jni_env) || get_class_name_method == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of $(Frame class).getClassName()Ljava/lang/String;\n");
(*jni_env)->DeleteLocalRef(jni_env, stack_frame_class);
return -1;
}
jstring class_name_of_frame_method = (*jni_env)->CallObjectMethod(jni_env, stack_frame, get_class_name_method);
- if ((*jni_env)->ExceptionOccurred(jni_env))
- {
- (*jni_env)->DeleteLocalRef(jni_env, stack_frame_class);
- (*jni_env)->ExceptionClear(jni_env);
- return -1;
- }
- if (class_name_of_frame_method == NULL)
+ if (check_and_clear_exception(jni_env) || class_name_of_frame_method == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class name of a class on a frame\n");
(*jni_env)->DeleteLocalRef(jni_env, stack_frame_class);
return -1;
}
@@ -1721,11 +1681,9 @@ static int print_stack_trace_element(
jclass class_of_frame_method = (*jni_env)->FindClass(jni_env, cls_name_str);
char *class_location = NULL;
- if ((*jni_env)->ExceptionOccurred(jni_env))
+ if (check_and_clear_exception(jni_env) || NULL == class_of_frame_method)
{
- VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": FindClass(%s) thrown an exception\n", cls_name_str);
- (*jni_env)->ExceptionClear(jni_env);
-
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get class of %s. Try more hard by searching in the loaded classes.\n", cls_name_str);
string_replace(cls_name_str, '/', '.');
class_of_frame_method = find_class_in_loaded_class(jvmti_env, jni_env, cls_name_str);
string_replace(cls_name_str, '.', '/');
@@ -1753,20 +1711,16 @@ static int print_stack_trace_element(
jmethodID to_string_method = (*jni_env)->GetMethodID(jni_env, stack_frame_class, "toString", "()Ljava/lang/String;");
(*jni_env)->DeleteLocalRef(jni_env, stack_frame_class);
- if (to_string_method == NULL)
+ if (check_and_clear_exception(jni_env) || to_string_method == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of $(Frame class).toString()Ljava/lang/String;\n");
return -1;
}
jobject orig_str = (*jni_env)->CallObjectMethod(jni_env, stack_frame, to_string_method);
- if ((*jni_env)->ExceptionOccurred(jni_env))
- {
- (*jni_env)->DeleteLocalRef(jni_env, orig_str);
- (*jni_env)->ExceptionClear(jni_env);
- return -1;
- }
- if (orig_str == NULL)
+ if (check_and_clear_exception(jni_env) || NULL == orig_str)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get a string representation of a class on a frame\n");
(*jni_env)->DeleteLocalRef(jni_env, orig_str);
return -1;
}
@@ -1801,21 +1755,17 @@ static int print_exception_stack_trace(
jclass exception_class = (*jni_env)->GetObjectClass(jni_env, exception);
jmethodID to_string_method = (*jni_env)->GetMethodID(jni_env, exception_class, "toString", "()Ljava/lang/String;");
- if (to_string_method == NULL)
+ if (check_and_clear_exception(jni_env) || to_string_method == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of $(Exception class).toString()Ljava/lang/String;\n");
(*jni_env)->DeleteLocalRef(jni_env, exception_class);
return -1;
}
jobject exception_str = (*jni_env)->CallObjectMethod(jni_env, exception, to_string_method);
- if ((*jni_env)->ExceptionCheck(jni_env))
- {
- (*jni_env)->DeleteLocalRef(jni_env, exception_class);
- (*jni_env)->ExceptionClear(jni_env);
- return -1;
- }
- if (exception_str == NULL)
+ if (check_and_clear_exception(jni_env) || exception_str == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get a string representation of a class on a frame\n");
(*jni_env)->DeleteLocalRef(jni_env, exception_class);
return -1;
}
@@ -1840,26 +1790,23 @@ static int print_exception_stack_trace(
jmethodID get_stack_trace_method = (*jni_env)->GetMethodID(jni_env, exception_class, "getStackTrace", "()[Ljava/lang/StackTraceElement;");
(*jni_env)->DeleteLocalRef(jni_env, exception_class);
- if (get_stack_trace_method == NULL)
+ if (check_and_clear_exception(jni_env) || get_stack_trace_method == NULL)
{
- VERBOSE_PRINT("Cannot get getStackTrace() method id");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of $(Exception class).getStackTrace()[Ljava/lang/StackTraceElement;\n");
return wrote;
}
jobject stack_trace_array = (*jni_env)->CallObjectMethod(jni_env, exception, get_stack_trace_method);
- if ((*jni_env)->ExceptionCheck(jni_env))
- {
- (*jni_env)->ExceptionClear(jni_env);
- return wrote;
- }
- if (stack_trace_array == NULL)
+ if (check_and_clear_exception(jni_env) || stack_trace_array == NULL)
{
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get a stack trace from an exception object\n");
return wrote;
}
jint array_size = (*jni_env)->GetArrayLength(jni_env, stack_trace_array);
for (jint i = 0; i < array_size; ++i)
{
+ /* Throws only ArrayIndexOutOfBoundsException and this should not happen */
jobject frame_element = (*jni_env)->GetObjectArrayElement(jni_env, stack_trace_array, i);
const int frame_wrote = print_stack_trace_element(jvmti_env,
@@ -1918,23 +1865,30 @@ static char *generate_thread_stack_trace(
wrote += exception_wrote;
+ /* GetObjectClass() throws nothing */
jclass exception_class = (*jni_env)->GetObjectClass(jni_env, exception);
if (NULL == exception_class)
{
- VERBOSE_PRINT("Cannot get class of an object\n");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Cannot get class of an object\n");
return stack_trace_str;
}
jmethodID get_cause_method = (*jni_env)->GetMethodID(jni_env, exception_class, "getCause", "()Ljava/lang/Throwable;");
(*jni_env)->DeleteLocalRef(jni_env, exception_class);
- if (NULL == get_cause_method)
+ if (check_and_clear_exception(jni_env) || NULL == get_cause_method)
{
- VERBOSE_PRINT("Cannot find get an id of getCause()Ljava/lang/Throwable; method\n");
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Could not get methodID of $(Exception class).getCause()Ljava/lang/Throwable;\n");
return stack_trace_str;
}
jobject cause = (*jni_env)->CallObjectMethod(jni_env, exception, get_cause_method);
+ if (check_and_clear_exception(jni_env))
+ {
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Failed to get an inner exception of the top most one;\n");
+ return stack_trace_str;
+ }
+
while (NULL != cause)
{
if ((size_t)(MAX_STACK_TRACE_STRING_LENGTH - wrote) < (sizeof(CAUSED_STACK_TRACE_HEADER) - 1))
@@ -1965,6 +1919,11 @@ static char *generate_thread_stack_trace(
jobject next_cause = (*jni_env)->CallObjectMethod(jni_env, cause, get_cause_method);
(*jni_env)->DeleteLocalRef(jni_env, cause);
+ if (check_and_clear_exception(jni_env))
+ {
+ VERBOSE_PRINT(__FILE__ ":" STRINGIZE(__LINE__)": Failed to get an inner exception of another inner one;\n");
+ return stack_trace_str;
+ }
cause = next_cause;
}
@@ -2318,14 +2277,14 @@ static void JNICALL callback_on_exception_catch(
}
jclass object_class = (*jni_env)->FindClass(jni_env, "java/lang/Object");
- if (NULL == object_class)
+ if (check_and_clear_exception(jni_env) || NULL == object_class)
{
VERBOSE_PRINT("Cannot find java/lang/Object class");
goto callback_on_exception_catch_exit;
}
jmethodID equal_method = (*jni_env)->GetMethodID(jni_env, object_class, "equals", "(Ljava/lang/Object;)Z");
- if (NULL == equal_method)
+ if (check_and_clear_exception(jni_env) || NULL == equal_method)
{
VERBOSE_PRINT("Cannot find java.lang.Object.equals(Ljava/lang/Object;)Z method");
(*jni_env)->DeleteLocalRef(jni_env, object_class);
@@ -2333,8 +2292,12 @@ static void JNICALL callback_on_exception_catch(
}
jboolean equal_objects = (*jni_env)->CallBooleanMethod(jni_env, exception_object, equal_method, rpt->exception_object);
- if (!equal_objects)
+ if (check_and_clear_exception(jni_env) || !equal_objects)
+ {
+ VERBOSE_PRINT("Cannot determine whether the caught exception is also the uncaught exception");
+ (*jni_env)->DeleteLocalRef(jni_env, object_class);
goto callback_on_exception_catch_exit;
+ }
/* Faster than get()-pop() approach is faster because it is search-and-search-free but
* pop()-push() approach is search-free-and-search-malloc
diff --git a/src/jthrowable_circular_buf.c b/src/jthrowable_circular_buf.c
index e13801c..64f0f30 100644
--- a/src/jthrowable_circular_buf.c
+++ b/src/jthrowable_circular_buf.c
@@ -162,6 +162,16 @@ static int jthrowable_circular_buf_find_index(T_jthrowableCircularBuf *buffer, j
}
jclass object_class = (*buffer->jni_env)->FindClass(buffer->jni_env, "java/lang/Object");
+ if ((*buffer->jni_env)->ExceptionOccurred(buffer->jni_env))
+ {
+ VERBOSE_PRINT("Cannot find java/lang/Object class\n");
+#ifdef VERBOSE
+ (*buffer->jni_env)->ExceptionDescribe(buffer->jni_env);
+#endif
+ (*buffer->jni_env)->ExceptionClear(buffer->jni_env);
+ return 1;
+ }
+
if (NULL == object_class)
{
VERBOSE_PRINT("Cannot find java/lang/Object class");
@@ -169,6 +179,16 @@ static int jthrowable_circular_buf_find_index(T_jthrowableCircularBuf *buffer, j
}
jmethodID equal_method = (*buffer->jni_env)->GetMethodID(buffer->jni_env, object_class, "equals", "(Ljava/lang/Object;)Z");
+ if ((*buffer->jni_env)->ExceptionOccurred(buffer->jni_env))
+ {
+ VERBOSE_PRINT("Cannot find java.lang.Object.equals(Ljava/lang/Object;)Z method\n");
+#ifdef VERBOSE
+ (*buffer->jni_env)->ExceptionDescribe(buffer->jni_env);
+#endif
+ (*buffer->jni_env)->ExceptionClear(buffer->jni_env);
+ return 1;
+ }
+
if (NULL == equal_method)
{
VERBOSE_PRINT("Cannot find java.lang.Object.equals(Ljava/lang/Object;)Z method");
@@ -182,10 +202,24 @@ static int jthrowable_circular_buf_find_index(T_jthrowableCircularBuf *buffer, j
for (size_t i = rbegin; /* break inside */; i = jthrowable_circular_buf_get_index(buffer, (i - 1)))
{
VERBOSE_PRINT("Checking next exception object %p\n", (void *)buffer->mem[i]);
- if (NULL != buffer->mem[i] && (*buffer->jni_env)->CallBooleanMethod(buffer->jni_env, buffer->mem[i], equal_method, exception))
+ if (NULL != buffer->mem[i])
{
- *index = i;
- return 0;
+ jboolean equals = (*buffer->jni_env)->CallBooleanMethod(buffer->jni_env, buffer->mem[i], equal_method, exception);
+ if ((*buffer->jni_env)->ExceptionOccurred(buffer->jni_env))
+ {
+ VERBOSE_PRINT("Cannot determine whether objects are equal\n");
+#ifdef VERBOSE
+ (*buffer->jni_env)->ExceptionDescribe(buffer->jni_env);
+#endif
+ (*buffer->jni_env)->ExceptionClear(buffer->jni_env);
+ return 1;
+ }
+
+ if (equals)
+ {
+ *index = i;
+ return 0;
+ }
}
if (rend == i)
--
1.8.3.1