On Sat, 10 Dec 2022 10:29:43 GMT, Alan Bateman <al...@openjdk.org> wrote:

>> I have a memory of the following concerning JVM/TI versions:
>> 
>> - if you asked for JVMTI_VERSION, then you got the highest version supported 
>> by the JVM.
>> - if you asked for JVMTI_VERSION_1, then you got the highest compatible 
>> version to VERSION_1.
>> - if you asked for JVMTI_VERSION_1_1, then you got JVMTI_VERSION_1_1, no 
>> more, no less if the JVM supports it.
>> 
>> Here's where things get gnarly:
>> - if you asked for JVMTI_VERSION_1, could you get back JVMTI_VERSION_1_2 or 
>> JVMTI_VERSION_9 or
>>   JVMTI_VERSION_11 if the JVM in question supported each of those versions 
>> (and no higher)?
>>   - the assumption that I've always made is that each of JVMTI_VERSION_1_N 
>> are all considered
>>     compatible so asked for JVMTI_VERSION_1, you would get the highest 
>> compatible version in
>>     the JVMTI_VERSION_1_N set that is supported by the JVM on which you ask 
>> the question.
>>   - if you ask for JVMTI_VERSION_1 on a JVM that supports JVMTI_VERSION_1_N 
>> and JVMTI_VERSION_9
>>     then I would expect you to get back JVMTI_VERSION_1_2 and not 
>> JVMTI_VERSION_9. Why?
>>   - My assumption is that you only change major version numbers when you 
>> make incompatible
>>     changes. Adding a new API is a compatible change because the older agent 
>> doesn't know how
>>     to use the new API. Changing the semantics of an existing API is NOT a 
>> compatible change so
>>     you bump the major number.
>> 
>> So I'm assuming that JVMTI_VERSION_9 has incompatible changes relative to 
>> JVMTI_VERSION_1_N.
>> Similarly I'm assuming that JVMTI_VERSION_11 has incompatible changes 
>> relative to JVMTI_VERSION_9
>> and JVMTI_VERSION_1_N.
>
>> I have a memory of the following concerning JVM/TI versions:
>> 
>> * if you asked for JVMTI_VERSION, then you got the highest version supported 
>> by the JVM.
> 
> JVMTI_VERSION is defined in jvmti.h so its value depends on which JDK include 
> directory was used when compiling the agent. If the JDK supports that version 
> then it is required to return a JVMTI env that is compatible or fail with 
> EVERSION. If the agent calls GetVersionNumber to see what version it got then 
> it may be a newer (but compatible) version, which is what our implementation 
> does. It may be that the agent was compiled with JVMTI_VERSION for a newer 
> JDK release, in which case GetEnv must fail with EVERSION as an older JDK 
> release doesn't know about new JVMTI versions.
> 
> In any case, there should be no mix'ing and matching with the JDWP agent so 
> GetEnv asking for JVMTI_VERSION should be okay. For a JDK build, the JVMTI 
> version at build time will match run-time. A hash of the jdk.jdwp.agent 
> module is generated at build/packaging time to prevent accidental linking 
> with modules from different JDK builds. If someone does attempt to run jlink 
> and use java.base from one build and jdk.jdwp.agent from another build then 
> they will get an error that the hashes don't match. It is of course possible 
> that someone does a slight of hand and copy a libjdwp/libdt_socket from one 
> JDK build into a build from a different JDK release but I don't think we need 
> to spend too much time on that as it's just not supported to do that. Also, 
> as Chris says, the version compatibility check should catch it too.
> 
> 
>> * if you asked for JVMTI_VERSION_1, then you got the highest compatible 
>> version to VERSION_1.
>> * if you asked for JVMTI_VERSION_1_1, then you got JVMTI_VERSION_1_1, no 
>> more, no less if the JVM supports it.
> 
> If you run on JDK 19 then you'll get a JVMTI_VERSION_19 in both cases. It 
> might be in the future that we need to do some incompatible changes to JVMTI, 
> like remove the deprecated heap functions, in which case it might have to 
> return EVERSION for both cases. The is a bridge that we haven't got to yet 
> but I expect it will require discussing JVMTI capabilities at the same time.
> 
> In passing, I see that JvmtiExport::get_jvmti_interface doesn't reject 
> 19.minor, I guess it should.

@AlanBateman  I agree with everything you say, but there is one advantage to 
using JVMTI_VERSION_1 instead of JVMTI_VERSION. With the former if you tried, 
for example, to drop the JDK 21 debug agent into a JDK 20 build, you will get:

`ERROR: This jdwp native library will not work with this VM's version of JVMTI 
(20.0.0). It needs JVMTI 21.0[.0].`

However, if you use JVMTI_VERSION, the error you will see is:

`ERROR: JDWP unable to access JVMTI Version 21.0.0 (0x30150000). JNIEnv's 
GetEnv() returned -3.`

This is because the first example passes the GetEnv() but then fails the 
version check, and the 2nd one fails the GetEnv(). Both are doing the right 
thing. It's just a matter of the preferable error message, and the 2nd seems 
better.

-------------

PR: https://git.openjdk.org/jdk/pull/11602

Reply via email to