[
https://issues.apache.org/jira/browse/HDFS-14348?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16790898#comment-16790898
]
Sahil Takiar commented on HDFS-14348:
-------------------------------------
Found some more issues:
{code}
static jthrowable hadoopRzOptionsGetEnumSet(JNIEnv *env,
struct hadoopRzOptions *opts, jobject *enumSet)
{
...
jclass clazz = (*env)->FindClass(env, READ_OPTION);
if (!clazz) {
jthr = newRuntimeError(env, "failed "
"to find class for %s", READ_OPTION);
goto done;
}
...
{code}
{code}
jthrowable newRuntimeError(JNIEnv *env, const char *fmt, ...)
{
char buf[512];
jobject out, exc;
jstring jstr;
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
jstr = (*env)->NewStringUTF(env, buf);
if (!jstr) {
// We got an out of memory exception rather than a RuntimeException.
// Too bad...
return getPendingExceptionAndClear(env);
}
...
{code}
The issue is that {{FindClass}} can throw an error, but the call to
{{newRuntimeError}} calls {{NewStringUTF}} without clearing the pending
exception possibly thrown by {{FindClass}}. According to
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#exception_handling
this is illegal; you cannot call {{NewStringUTF}} while there is an exception
pending.
I think I missed this in HDFS-14321: {{hadoopRzOptionsSetByteBufferPool}} calls
{{opts->byteBufferPool = (*env)->NewGlobalRef(env, byteBufferPool)}} but does
not check for exceptions afterwards.
> Fix JNI exception handling issues in libhdfs
> --------------------------------------------
>
> Key: HDFS-14348
> URL: https://issues.apache.org/jira/browse/HDFS-14348
> Project: Hadoop HDFS
> Issue Type: Bug
> Components: hdfs-client, libhdfs, native
> Reporter: Sahil Takiar
> Assignee: Sahil Takiar
> Priority: Major
>
> During some manual digging through the libhdfs code, we found several places
> where we are not handling exceptions properly.
> Specifically, there seem to be some violation of the following snippet from
> the JNI Oracle docs
> (https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#exceptions_and_error_codes):
> {quote}
> *Exceptions and Error Codes*
> Certain JNI functions use the Java exception mechanism to report error
> conditions. In most cases, JNI functions report error conditions by returning
> an error code and throwing a Java exception. The error code is usually a
> special return value (such as NULL) that is outside of the range of normal
> return values. Therefore, the programmer can quickly check the return value
> of the last JNI call to determine if an error has occurred, and call a
> function, ExceptionOccurred(), to obtain the exception object that contains a
> more detailed description of the error condition.
> There are two cases where the programmer needs to check for exceptions
> without being able to first check an error code:
> [1] The JNI functions that invoke a Java method return the result of the Java
> method. The programmer must call ExceptionOccurred() to check for possible
> exceptions that occurred during the execution of the Java method.
> [2] Some of the JNI array access functions do not return an error code, but
> may throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
> In all other cases, a non-error return value guarantees that no exceptions
> have been thrown.
> {quote}
> Here is a running list of issues:
> * {{classNameOfObject}} in {{jni_helper.c}} calls {{CallObjectMethod}} but
> does not check if an exception has occurred, it only checks if the result of
> the method (in this case {{Class#getName(String)}}) returns {{NULL}}
> * Exception handling in {{get_current_thread_id}} (both
> {{posix/thread_local_storage.c}} and {{windows/thread_local_storage.c}})
> seems to have several issues; lots of JNI methods are called without checking
> for exceptions
> * Most of the calls to {{GetObjectArrayElement}} and {{GetByteArrayRegion}}
> in {{hdfs.c}} do not check for exceptions properly
> ** e.g. for {{GetObjectArrayElement}} they only check if the result of the
> operation is {{NULL}}, but they should call {{ExceptionOccurred}} to look for
> pending exceptions as well
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]