Skip to content

JNI local references accumulate in Platform_init symbol loop #125

Description

@QiuYucheng2003

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions