Author: amiloslavskiy
Date: Thu Oct 15 10:17:19 2020
New Revision: 1882524
URL: http://svn.apache.org/viewvc?rev=1882524&view=rev
Log:
JavaHL: Make sure that TunnelAgent is cleaned up on pending exception
See the previous commit for explanation why cleanup is important.
Before this commit, if there was a pending Java exception (such as SVN
error), 'OperationContext::closeTunnel()' early-returned on
'isJavaExceptionThrown()'.
At the same time, calling Java methods in 'close_TunnelChannel()'
requires that there are no pending Java exceptions. Use
'StashException' to temporarily move it out of the way.
This crash is demonstrated by the following JavaHL tests:
* testCrash_RequestChannel_nativeRead_AfterException
* testCrash_RequestChannel_nativeRead_AfterSvnError
This commit alone does not fix all problems in these tests, see
previous and next commits as well.
[in subversion/bindings/javahl]
* native/OperationContext.cpp
Use 'StashException' to move temporarily exception out of the way.
Modified:
subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp
Modified:
subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp
URL:
http://svn.apache.org/viewvc/subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp?rev=1882524&r1=1882523&r2=1882524&view=diff
==============================================================================
---
subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp
(original)
+++
subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp
Thu Oct 15 10:17:19 2020
@@ -691,19 +691,25 @@ OperationContext::closeTunnel(void *tunn
delete tc;
JNIEnv *env = JNIUtil::getEnv();
- if (JNIUtil::isJavaExceptionThrown())
- return;
+
+ // Cleanup is important, otherwise TunnelAgent may crash when
+ // accessing freed native objects. For this reason, cleanup is done
+ // despite a pending exception. If more exceptions occur, they are
+ // stashed as well in order to complete all cleanup steps.
+ StashException ex(env);
if (jclosecb)
callCloseTunnelCallback(env, jclosecb);
if (jrequest)
{
+ ex.stashException();
close_TunnelChannel(env, jrequest);
}
if (jresponse)
{
+ ex.stashException();
close_TunnelChannel(env, jresponse);
}
}