RFR (S): JDK-8164086: Checked JNI pending exception check should be cleared when returning to Java frame
David Holmes
david.holmes at oracle.com
Fri Aug 26 00:27:31 UTC 2016
Hi David,
I'm missing some pieces of this puzzle I'm afraid.
On 25/08/2016 8:05 PM, David Simms wrote:
>
> Updated the webrev here:
> http://cr.openjdk.java.net/~dsimms/8164086/webrev1/
hotspot/src/share/vm/prims/whitebox.cpp
First I'm not sure that Whitebox isn't a special case here that could be
handled in the WB_START/END macros - see below.
More generally you state below that the transition from native back to
the VM doesn't have to do anything with the pending_exception_check flag
because well behaved native code in that context will explicitly check
for exceptions, and so the pending-exception-check will already be
disabled before returning to Java. First, if that is the case then we
should assert that it is so in the native->VM return transition.
Second though, it doesn't seem to be the case in Whitebox because the
CHECK_JNI_EXCEPTION_ macro simply calls HAS_PENDING_EXCEPTION and so
won't touch the pending-exception-check flag. ??
It was a good pick up that some whitebox code was using values that
might be NULL because an exception had occurred. There are a couple of
changes that are unnecessary though:
1235 result = env->NewObjectArray(5, clazz, NULL);
1236 CHECK_JNI_EXCEPTION_(env, NULL);
1237 if (result == NULL) {
1238 return result;
1239 }
(and similarly at 1322)
result will be NULL iff there is a pending exception; and vice-versa. So
the existing check for NULL suffices for correctness. If you want to
check exceptions for the side-effect of clearing the
pending-exception-check flag then lines 1237-1239 can be deleted.
However I would suggest that if you truly do want to clear the
pending-exception-check flag then the place to do it is the WB_END
macro. That allows allows exception checks at the end of methods, eg:
1261 env->SetObjectArrayElement(result, 4, entry_point);
1262 CHECK_JNI_EXCEPTION_(env, NULL);
1263
1264 return result;
to be elided.
---
hotspot/src/share/vm/runtime/thread.hpp
! // which function name. Returning to a Java frame should implicitly
clear the
! // need for, this is done for Native->Java transitions.
Seems to be some text missing after "need for".
---
For the tests we no longer use bug numbers as part of the test names.
Looks like some recent tests slipped by unfortunately. :(
You should be able to get rid of the:
* @modules java.base/jdk.internal.misc
with Christian's just pushed changes to ProcessTools to isolate the
Unsafe dependency.
> core-libs & Kumar: java launcher: are you okay with the
> CHECK_EXCEPTION_PRINT macro, or would you rather it was silent (i.e.
> CHECK_EXCEPTION_RETURN) ?
I'm not seeing the point of this logic. Any exceptions that remain
pending when the main thread detaches from the VM will be reported by
the uncaught-exception handling logic. The checks you put in are in most
cases immediately before a return so there is no need to check for a
pending exception and do an earlier return. And in one case you would
bypass tracing logic by doing an early return.
I had assumed this was just some debugging code you had left in by mistake.
Thanks,
David H.
-------
> In-line...
>
>
> On 23/08/16 14:16, David Holmes wrote:
>> Hi David
>>
>> On 23/08/2016 8:24 PM, David Simms wrote:
>>>
>>> Reply in-line...
>>>
>>> On 19/08/16 14:29, David Holmes wrote:
>>>> Hi David,
>>>>
>>>>
>>>> The changes in the native wrapper seem okay though I'm not an expert
>>>> on the machine specific encodings.
>>>>
>>>> I'm a little surprised there are not more things that need changing
>>>> though. Does the JIT use those wrappers too?
>>>
>>> Yeah they do, I double checked Nils from compiler group. I also tested
>>> with -Xcomp, test failed without sharedRuntime fix. The test execution
>>> time was over 10 seconds, so I removed it from the jtreg test itself
>>> (hard-coded ProcessTools.executeTestJVM()) since it is part of
>>> "hotspot_fast_runtime".
>>>
>>>> Can we transition from Java to VM to native and then back - and if so
>>>> might we need to clear the pending exception check? (I'm not sure if
>>>> from in the VM a native call could actually be a JNI call, or will
>>>> only be a direct native call?).
>>>
>>> At first I thought JavaCallWrapper needs it, following all the places we
>>> manipulate the thread's active handle block (besides manual push/pop).
>>> But then call helper just ends up calling the native wrapper, which
>>> takes care of it. Not a direct native call. So I left it, as-is.
>>
>> That's not the case I was thinking of. We have ThreadToNativeFromVM
>> and then we do native stuff - if any of that were JNI-based (perhaps
>> it is not) then we would enable the check but not disable it again
>> when returning from VM to Java.
>>
>
>
> Got you now: Java->VM->Native i.e. VM code using JNI may miss an
> exception check. So I check the call hierarchy from
> "ThreadToNativeFromVM" and found whitebox.cpp had a few spots where
> checks were missing, added them in now.
>
> There's an extra comment stating ThreadToNativeFromVM is expected to be
> "well behaved" (i.e. check for exceptions), which it is with the
> whitebox.cpp fixes, so we don't require any extra code or overhead in
> VM->Java transitions. As far as maintaining "well behaved" JNI code, we
> do static code checking with "Parfait" as part of testing, and there are
> a few other related bugs that already exist to address these issues.
>
>>>>
>>>> Did you intend to leave in the changes to
>>>> jdk/src/java.base/share/native/libjli/java.c? It looks like debug/test
>>>> code to me.
>>>
>>> The launcher produces warnings (Java method invokes) that break the
>>> jtreg test, so yeah, thought it was best to check and print them. Some
>>> of the existing code checks and silently returns, I followed the same
>>> pattern where that pattern was in place.
>>
>> This needs to be looked at closer then and reviewed by the launcher
>> folk (ie Kumar).
>
> CC:ed core-libs & Kumar. Thanks for pointing that out.
>
>>
>>>>
>>>> The test I'm finding a bit hard to follow but don't you need to check
>>>> for pending exceptions here:
>>>>
>>>> 29 static jmethodID get_method_id(JNIEnv *env, jclass clz, jstring
>>>> jname, jstring jsig) {
>>>> 30 jmethodID mid;
>>>> 31 const char *name, *sig;
>>>> 32 name = (*env)->GetStringUTFChars(env, jname, NULL);
>>>> 33 sig = (*env)->GetStringUTFChars(env, jsig, NULL);
>>>> 34 mid = (*env)->GetMethodID(env, clz, name, sig);
>>>>
>>>> to avoid triggering the warning?
>>>>
>>> Those methods don't require an explicit check since there return values
>>> denote an error condition.
>>>
>>> Whilst Java invoke return values are user defined, so they do need
>>> it
>>> https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#asynchronous_exceptions).
>>>
>>>
>>> Technically array stores need to check for AIOOBE, but given most
>>> code handles index/bounds checks, it seemed way too pedantic
>>> (commented in jniCheck.cpp:176).
>>
>> Not following. GetStringUTFChars can post OOME so we would enable the
>> check-flag if that happens on the first call above, then the second
>> call would be made with the exception pending and trigger the warning.
>
> So as we mentioned off-list, yes this test code should also follow spec,
> updated.
>
> Thanks for looking at this, David
> /David Simms
>
More information about the core-libs-dev
mailing list