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

Reply via email to