From 6583ad148be5447eb2f086a2c6c7006631dff4da Mon Sep 17 00:00:00 2001 From: cnauroth Date: Thu, 5 Feb 2015 16:53:34 -0800 Subject: [PATCH] HADOOP-11526. Memory leak in Bzip2Compressor and Bzip2Decompressor. Contributed by Anu Engineer. --- .../hadoop-common/CHANGES.txt | 3 ++ .../io/compress/bzip2/Bzip2Compressor.c | 28 +++++++++++++++---- .../io/compress/bzip2/Bzip2Decompressor.c | 28 +++++++++++++++---- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 8b73d5afff..aee3a23b60 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -864,6 +864,9 @@ Release 2.7.0 - UNRELEASED HADOOP-11543. Improve help message for hadoop/yarn command. (Brahma Reddy Battula via ozawa) + HADOOP-11526. Memory leak in Bzip2Compressor and Bzip2Decompressor. + (Anu Engineer via cnauroth) + Release 2.6.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Compressor.c b/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Compressor.c index d4cd6dfbd2..ef81bea2ce 100644 --- a/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Compressor.c +++ b/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Compressor.c @@ -43,15 +43,25 @@ JNIEXPORT void JNICALL Java_org_apache_hadoop_io_compress_bzip2_Bzip2Compressor_initIDs( JNIEnv *env, jclass class, jstring libname) { - const char* bzlib_name = (*env)->GetStringUTFChars(env, libname, NULL); - if (strcmp(bzlib_name, "system-native") == 0) - bzlib_name = HADOOP_BZIP2_LIBRARY; + const char *bzlib_name = NULL; + const char *java_lib_name = (*env)->GetStringUTFChars(env, libname, NULL); + if (java_lib_name == NULL) { + // Java code will get OutOfMemoryException thrown by GetStringUTFChars + goto cleanup; + } + + if (strcmp(java_lib_name, "system-native") == 0) { + bzlib_name = HADOOP_BZIP2_LIBRARY; + } else { + bzlib_name = java_lib_name; + } + // Load the native library. void *libbz2 = dlopen(bzlib_name, RTLD_LAZY | RTLD_GLOBAL); if (!libbz2) { THROW(env, "java/lang/UnsatisfiedLinkError", "Cannot load bzip2 native library"); - return; + goto cleanup; } // Locate the requisite symbols from libbz2.so. @@ -83,6 +93,11 @@ Java_org_apache_hadoop_io_compress_bzip2_Bzip2Compressor_initIDs( "Ljava/nio/Buffer;"); Bzip2Compressor_directBufferSize = (*env)->GetFieldID(env, class, "directBufferSize", "I"); + cleanup: + if(java_lib_name != NULL) { + (*env)->ReleaseStringUTFChars(env,libname,java_lib_name); + java_lib_name = NULL; + } } JNIEXPORT jlong JNICALL @@ -234,9 +249,10 @@ Java_org_apache_hadoop_io_compress_bzip2_Bzip2Compressor_end( { if (dlsym_BZ2_bzCompressEnd(BZSTREAM(stream)) != BZ_OK) { THROW(env, "java/lang/InternalError", NULL); - } else { - free(BZSTREAM(stream)); } + + free(BZSTREAM(stream)); + } JNIEXPORT jstring JNICALL diff --git a/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Decompressor.c b/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Decompressor.c index b6c5213524..ad9bcb72c6 100644 --- a/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Decompressor.c +++ b/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/compress/bzip2/Bzip2Decompressor.c @@ -42,15 +42,25 @@ JNIEXPORT void JNICALL Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_initIDs( JNIEnv *env, jclass class, jstring libname) { - const char* bzlib_name = (*env)->GetStringUTFChars(env, libname, NULL); - if (strcmp(bzlib_name, "system-native") == 0) - bzlib_name = HADOOP_BZIP2_LIBRARY; + const char *bzlib_name = NULL; + const char *java_lib_name = (*env)->GetStringUTFChars(env, libname, NULL); + if (java_lib_name == NULL) { + // Java code will get OutOfMemoryException thrown by GetStringUTFChars + goto cleanup; + } + + if (strcmp(java_lib_name, "system-native") == 0) { + bzlib_name = HADOOP_BZIP2_LIBRARY; + } else { + bzlib_name = java_lib_name; + } + // Load the native library. void *libbz2 = dlopen(bzlib_name, RTLD_LAZY | RTLD_GLOBAL); if (!libbz2) { THROW(env, "java/lang/UnsatisfiedLinkError", "Cannot load bzip2 native library"); - return; + goto cleanup; } // Locate the requisite symbols from libbz2.so. @@ -80,6 +90,11 @@ Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_initIDs( "Ljava/nio/Buffer;"); Bzip2Decompressor_directBufferSize = (*env)->GetFieldID(env, class, "directBufferSize", "I"); +cleanup: + if(java_lib_name != NULL) { + (*env)->ReleaseStringUTFChars(env,libname,java_lib_name); + java_lib_name = NULL; + } } JNIEXPORT jlong JNICALL @@ -237,9 +252,10 @@ Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_end( { if (dlsym_BZ2_bzDecompressEnd(BZSTREAM(stream)) != BZ_OK) { THROW(env, "java/lang/InternalError", 0); - } else { - free(BZSTREAM(stream)); } + + free(BZSTREAM(stream)); + } /**