RFR: 8282773: Refactor parsing of integer VM options [v2]

Ioi Lam iklam at openjdk.java.net
Thu Mar 10 04:49:15 UTC 2022


On Thu, 10 Mar 2022 04:03:35 GMT, David Holmes <dholmes at openjdk.org> wrote:

>> I tried changing the code to this. It doesn't work. "0x123456789" is incorrectly parsed to 591751049 for the `int` flag `AVX3Threshold` without setting `errno`:
>> 
>> 
>> template <typename T, ENABLE_IF(std::is_signed<T>::value), ENABLE_IF(sizeof(T) == 4)> // signed 32-bit
>> static bool parse_integer_impl(const char *s, char **endptr, int base, T* result) {
>>   errno = 0; // errno is thread safe
>>   *result = strtol(s, endptr, base);
>>   return errno == 0;
>> }
>> 
>> $ java -XX:AVX3Threshold=0 --version
>> java 19-internal 2022-09-20
>> Java(TM) SE Runtime Environment (slowdebug build 19-internal-adhoc.iklam.ken)
>> Java HotSpot(TM) 64-Bit Server VM (slowdebug build 19-internal-adhoc.iklam.ken, mixed mode, sharing)
>> $ java -XX:AVX3Threshold=0x123456789 --version
>> AVX3Threshold ( 591751049 ) must be 0 or a power of two value between 0 and MAX_INT
>> Error: Could not create the Java Virtual Machine.
>> Error: A fatal exception has occurred. Program will exit.
>> 
>> $ gcc --version
>> gcc (GCC) 10.3.0
>> $ uname -a
>> Linux host 5.13.0-28-generic #31-Ubuntu SMP Thu Jan 13 17:41:06 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
>> 
>> 
>> My stand-alone test case:
>> 
>> 
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <errno.h>
>> 
>> int main(int argc, char** argv) {
>>   if (argc >= 2) {
>>     char* endptr;
>> 
>>     errno = 0;    
>>     int n = strtol(argv[1], &endptr, 16);
>>     printf("errno = %d, strtol() returns %d == 0x%x\n", errno, n, n);
>>   }
>> }
>> 
>> $ gcc -g strtol.cpp -o strtol
>> $ ./strtol 0x12345678
>> errno = 0, strtol() returns 305419896 == 0x12345678
>> $ ./strtol 0x123456789
>> errno = 0, strtol() returns 591751049 == 0x23456789
>
> Okay so what you really mean is strtol can't be used to check for underflow/overflow of a 32-bit value when using a 64-bit build, because it is actually testing a 64-bit value. So you need different logic for sizeof(long)==4 and sizeof(long)==8. For a 32-bit build you can use strtol directly. For 64-bit you have to add explicit overflow and underflow checks.

I changed the code to use strtol/strtoul for the 32-bit numbers. On LP64 builds, I added explicitly range checks are you suggested.

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

PR: https://git.openjdk.java.net/jdk/pull/7763


More information about the hotspot-runtime-dev mailing list