RFR (S) 8229900: RedefineDeleteJmethod.java fails with -Xcheck:jni

coleen.phillimore at oracle.com coleen.phillimore at oracle.com
Wed Oct 2 22:11:08 UTC 2019


I added more checks (as discussed below) and reran tier1 with -Xcheck:jni.

http://cr.openjdk.java.net/~coleenp/2019/8229900.02/webrev/index.html

thanks,
Coleen

On 10/2/19 10:03 AM, coleen.phillimore at oracle.com wrote:
>
>
> On 10/2/19 12:53 AM, David Holmes wrote:
>> Hi Coleen,
>>
>> Sorry rather long-winded reply ...
>>
>> On 1/10/2019 11:52 pm, coleen.phillimore at oracle.com wrote:
>>> Summary: Remove RedefineClasses adjustment and test, but improve 
>>> checking for method/class matching.
>>>
>>> Tested with tier1 with -Xcheck:jni locally, and tier1 on Oracle 
>>> platforms.
>>>
>>> open webrev at 
>>> http://cr.openjdk.java.net/~coleenp/2019/8229900.01/webrev
>>> bug link https://bugs.openjdk.java.net/browse/JDK-8229900
>>
>> I was troubled by this change because it made me think more deeply 
>> about what should reasonably happen with respect to jmethodIDs and 
>> class redefinition.
>>
>> I had a (simplistic?) mental model that a jmethodID is a "pointer" to 
>> a specific method in a specific class (the defining class of the 
>> method). As such a jmethodID should only be used when operating on 
>> that class (or subclass thereof) or an instance of that class (or 
>> subclass thereof). With that mental model it makes sense for 
>> Xcheck:jni to validate the defining class is the target class, or a 
>> superclass thereof. But it doesn't then make sense for class 
>> redefinition to update jmethodIDs as the redefined class is not the 
>> original class! If a class is redefined then it should, in my mental 
>> model, invalidate all existing jmethodIDs that pertained to the 
>> original class.
>>
>> However, that's not very user friendly in the face of redefinition of 
>> a superclass as code that only works with the subclass may reasonably 
>> expect jmethodIDs to remain valid even if they refer to an inherited 
>> method that has been redefined. So we update them to refer to the 
>> redefined method implementation.
>>
>> So in that regards the update to jniCheck::validate_call_class seems 
>> correct. Though I wonder if we also need to check that obj->class is 
>> a subtype of clazz? As far as I can see we never actually validate 
>> that! We use the jmethodID to find the method and we then find the 
>> vtable index wrt. the method->holder class, and then we use that 
>> vtable index to lookup a method in the receiver object's class - 
>> which could lead to a random method being selected in a different class!
>
> I just added this check and am testing it now.
> Coleen
>>
>> Continuing on, if we do expect jmethodIDs to get updated upon class 
>> redefinition then it makes sense to me to keep the logic that handles 
>> deleted methods, by redirecting them to a method that throws NSME. 
>> The fact that method is in Unsafe is unfortunate but it is what we do 
>> elsewhere in the VM. I'm assuming the problem here is that the 
>> augmented jniCheck::validate_call_class will fail in such cases? That 
>> is a problem, but I think I'd rather see it special-cased than change 
>> the existing behaviour:
>>
>>   if (obj != NULL) {
>>     jniCheck::validate_object(thr, obj);
>>   }
>> + if (m == Universe::throw_no_such_method_error())
>> +   return;  // skip class checks in this case
>>
>> then the test could also remain.
>>
>> Also note that while we generally require JNI programmers to ensure 
>> everything is called correctly, jmethodIDs are also used by JVM TI 
>> and we tend to want JVM TI to have well defined semantics. I'm 
>> unclear now what happens if we invoke a deleted method through JVM TI ?
>>
>> Thanks,
>> David
>> ----
>>
>>> Thanks,
>>> Coleen
>



More information about the hotspot-runtime-dev mailing list