RFR: 8282773: Refactor parsing of integer VM options [v2]
David Holmes
dholmes at openjdk.java.net
Thu Mar 10 04:06:45 UTC 2022
On Thu, 10 Mar 2022 03:33:00 GMT, Ioi Lam <iklam at openjdk.org> wrote:
>> src/hotspot/share/runtime/arguments.cpp line 751:
>>
>>> 749: static bool parse_integer_impl(const char *s, char **endptr, int base, T* result) {
>>> 750: // Can't use strtol because it doesn't detect (at least on Linux/gcc) overflowing
>>> 751: // input such as "0x123456789" or "-0x800000001"
>>
>> This doesn't seem to be true in general. The Linux manpage indicates overflow and underflow are detected. And a simple test program confirms:
>>
>>
>> > ./conversion
>> Overflow detected okay for 0x123456789 (val = 2147483647)
>> Overflow detected okay for -0x800000001 (val = -2147483648)
>
> 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.
-------------
PR: https://git.openjdk.java.net/jdk/pull/7763
More information about the hotspot-runtime-dev
mailing list