Summary
Platform_init creates multiple JNI local references on each matching-symbol iteration but never releases them.
Affected code:
|
for (iSym = 0; iSym < nSyms; iSym++) { |
|
const char* symbolName = dlSymsName(pSyms, iSym); |
|
if (!strcmp(*symbolName == '_' ? symbolName + 1 : symbolName, "Java_org_bridj_${replacedSubPackage}_Platform_init")) |
|
continue; |
|
|
|
if (strstr(symbolName, packagePattern)) { |
|
if ((meth.fnPtr = getSelfSymbol(pLib, symbolName))) { |
|
jstring declaringClassName = (*env)->CallStaticObjectMethod(env, signatureHelperClass, decodeVersionSpecificMethodNameClassAndSignatureMethod, (*env)->NewStringUTF(env, symbolName), nameAndSigArray); |
|
|
|
if ((*env)->ExceptionCheck(env)) { |
|
printf("ERROR: Exception when trying to find method for symbol '%s'\n", symbolName); |
|
goto version_specific_init_failed; |
|
} |
|
|
|
if (declaringClassName) { |
|
jstring methodName = (*env)->GetObjectArrayElement(env, nameAndSigArray, 0); |
|
jstring methodSignature = (*env)->GetObjectArrayElement(env, nameAndSigArray, 1); |
|
const char* declaringClassNameStr = (char*)GET_CHARS(declaringClassName); |
|
jclass declaringClass = (*env)->FindClass(env, declaringClassNameStr); |
|
meth.name = (char*)GET_CHARS(methodName); |
|
meth.signature = (char*)GET_CHARS(methodSignature); |
|
|
|
//printf("INFO: Registering %s.%s with signature %s as %s\n", declaringClassNameStr, meth.name, meth.signature, symbolName); |
|
(*env)->RegisterNatives(env, declaringClass, &meth, 1); |
|
|
|
RELEASE_CHARS(methodName, meth.name); |
|
RELEASE_CHARS(methodSignature, meth.signature); |
|
RELEASE_CHARS(declaringClassName, declaringClassNameStr); |
|
} else { |
|
printf("ERROR: Failed to find method for symbol '%s'\n", symbolName); |
|
} |
The unreleased references include:
- Temporary
jstring from NewStringUTF
declaringClassName
methodName
methodSignature
declaringClass
RELEASE_CHARS only releases buffers returned by GetStringUTFChars; it does not release the corresponding JNI references.
Impact
When many symbols match, local references accumulate until the native method returns. This may exhaust the JNI local reference table and cause initialization failure or a JVM crash.
Suggested fix
Release per-iteration references with DeleteLocalRef after use, including the temporary NewStringUTF result. Alternatively, wrap each iteration with PushLocalFrame / PopLocalFrame.
Function-level references such as objectClass, signatureHelperClass, and nameAndSigArray should also be released before returning.
Summary
Platform_initcreates multiple JNI local references on each matching-symbol iteration but never releases them.Affected code:
BridJ/src/main/velocity/org/bridj/Init.c
Lines 69 to 99 in a035d1d
The unreleased references include:
jstringfromNewStringUTFdeclaringClassNamemethodNamemethodSignaturedeclaringClassRELEASE_CHARSonly releases buffers returned byGetStringUTFChars; it does not release the corresponding JNI references.Impact
When many symbols match, local references accumulate until the native method returns. This may exhaust the JNI local reference table and cause initialization failure or a JVM crash.
Suggested fix
Release per-iteration references with
DeleteLocalRefafter use, including the temporaryNewStringUTFresult. Alternatively, wrap each iteration withPushLocalFrame/PopLocalFrame.Function-level references such as
objectClass,signatureHelperClass, andnameAndSigArrayshould also be released before returning.