Dear Subversion Developers:

I attach a patch for the invalid local references in the
"CopySources.cpp", and the log message is here:

[[[
* subversion/bindings/javahl/native/CopySources.cpp
(array): Replace "JNIStringHolder" with two calls to
"GetStringUTFChars" and "DeleteLocalRef".
]]]

To produce this bug, run your JavaHL regression test under our dynamic
bug detector, Jinn [http://userweb.cs.utexas.edu/~bclee/jinn]:

$env JAVA_TOOL_OPTIONS=-agentlib:jinn make check-javahl
...
................Exception in thread "main"
xtc.lang.blink.agent.JNIAssertionFailure: The JNI reference 0x6857e68c
is dead in the argument 2 of ReleaseStringUTFChars.
        at 
xtc.lang.blink.agent.JNIAssertionFailure.assertFail(JNIAssertionFailure.java:16)
        at org.apache.subversion.javahl.SVNClient.copy(Native Method)
        at org.apache.subversion.javahl.BasicTests.testCopy(BasicTests.java:913)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at junit.framework.TestCase.runTest(TestCase.java:164)
        at junit.framework.TestCase.runBare(TestCase.java:130)
        at junit.framework.TestResult$1.protect(TestResult.java:106)
        at junit.framework.TestResult.runProtected(TestResult.java:124)
        at junit.framework.TestResult.run(TestResult.java:109)
        at junit.framework.TestCase.run(TestCase.java:120)
        at junit.framework.TestSuite.runTest(TestSuite.java:230)
        at junit.framework.TestSuite.run(TestSuite.java:225)
        at junit.framework.TestSuite.runTest(TestSuite.java:230)
        at junit.framework.TestSuite.run(TestSuite.java:225)
        at junit.textui.TestRunner.doRun(TestRunner.java:121)
        at junit.textui.TestRunner.doRun(TestRunner.java:114)
        at junit.textui.TestRunner.run(TestRunner.java:77)
        at org.apache.subversion.javahl.RunTests.main(RunTests.java:116)
...

The relevant source lines are here.

$ cat -n  subversion/bindings/javahl/native/CopySources.cpp
...
    85  apr_array_header_t *
    86  CopySources::array(SVN::Pool &pool)
    87  {
...
    99    for (std::vector<jobject>::const_iterator it = sources.begin();
   100          it < sources.end(); ++it)
   101      {
...
   119        JNIStringHolder path(jpath);
...
   126        env->DeleteLocalRef(jpath);
...
   170      }
...
   175  }

The "array" method allocates, and frees and uses a local reference at
Line 119, 126, and 99. The use at Line 99 is implicit. because C++
destructor of "JNIStringHolder" runs before the second iteration of
the for loop from Line 99 to 170. The source lines and calling context
at the pointer of failure  are here.

$cat -n ./subversion/bindings/javahl/native/JNIStringHolder.cpp
...
    46  JNIStringHolder::~JNIStringHolder()
    47  {
    48    if (m_jtext && m_str)
    49      m_env->ReleaseStringUTFChars(m_jtext, m_str);
    50  }


~JNIStringHolder at subversion/bindings/javahl/native/JNIStringHolder.cpp:49
CopySources::array  at subversion/bindings/javahl/native/CopySources.cpp:99
SVNClient::copyat subversion/bindings/javahl/native/SVNClient.cpp:438
Java_org_apache_subversion_javahl_SVNClient_copyat
subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp:588

I looked at the definition and uses of "JNIStringHolder",  and It's
better not to use the "JNIStringHolder" within a loop. My patch
replaces "JNIStringHolder" with a few calls to JNI functions.

Regards,
Byeong
Index: subversion/bindings/javahl/native/CopySources.cpp
===================================================================
--- subversion/bindings/javahl/native/CopySources.cpp	(revision 947057)
+++ subversion/bindings/javahl/native/CopySources.cpp	(working copy)
@@ -116,11 +116,12 @@
       if (JNIUtil::isJavaExceptionThrown())
         return NULL;
 
-      JNIStringHolder path(jpath);
+      const char * path = env->GetStringUTFChars(jpath, NULL);
       if (JNIUtil::isJavaExceptionThrown())
         return NULL;
 
-      src->path = apr_pstrdup(p, (const char *) path);
+      src->path = apr_pstrdup(p, path);
+      env->ReleaseStringUTFChars(jpath, path);
       SVN_JNI_ERR(JNIUtil::preprocessPath(src->path, pool.pool()),
                   NULL);
       env->DeleteLocalRef(jpath);

Reply via email to