JDK-8339313 : 32-bit build broken
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 24
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2024-08-30
  • Updated: 2024-12-25
  • Resolved: 2024-12-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 25
25 b03Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Building linux x86 now gets an error:

```
* For target support_test_hotspot_jtreg_native_support_libNoClassDefFoundErrorTest_libNoClassDefFoundErrorTest.o:
In file included from /usr/include/string.h:495,
                 from /shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:27:
In function ‘memset’,
    inlined from ‘giant_string’ at /shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:53:9,
    inlined from ‘Java_NoClassDefFoundErrorTest_tryCallDefineClass’ at /shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:61:20:
/usr/include/i386-linux-gnu/bits/string_fortified.h:71:10: error: ‘__builtin_memset’ writing 18446744071562067969 bytes into a region of size 2147483650 [-Werror=stringop-overflow=]
   71 |   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c: In function ‘Java_NoClassDefFoundErrorTest_tryCallDefineClass’:
/shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:51:20: note: at offset 0 to an object with size 2147483650 allocated by ‘malloc’ here
   51 |     char* c_name = malloc(len * sizeof(char));
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘giant_string’,
    inlined from ‘Java_NoClassDefFoundErrorTest_tryCallDefineClass’ at /shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:61:20:
/shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:54:25: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=]
   ... (rest of output omitted)
```

My configure line:

```
--with-boot-jdk=/shared/projects/openjdk/jdks/sapmachine22 --with-gtest=/shared/projects/openjdk/gtest/googletest-1.14.0 --with-debug-level=fastdebug --with-native-debug-symbols=internal -with-extra-cxxflags=-fno-omit-frame-pointer -with-extra-cflags=-fno-omit-frame-pointer --with-target-bits=32 --disable-precompiled-headers
```

----

At first glance, the warning seems to be bogus. I have yet to see a GCC fortify message that makes sense :-|

A workaround would be to just disable this coding for 32-bits, since the test is only run for 64 bit anyway.

============

Update: JDK-8338888 broke the build originally, but at least  JDK-8339307 also broke the build afterward (since nobody builds), so this issue is now about fixing all these issues.

Comments
Changeset: e9ad27fc Branch: master Author: Thomas Stuefe <stuefe@openjdk.org> Date: 2024-12-12 18:53:33 +0000 URL: https://git.openjdk.org/jdk/commit/e9ad27fcdcb59be573ffd20811e82bced7c78948
12-12-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/22707 Date: 2024-12-12 11:39:33 +0000
12-12-2024

[~dholmes] > It still seems to me this hinges on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100477 You are absolutely right, I used that bugzilla to reproduce and understand the bug. Thank you for the hint.
12-12-2024

I'd context switched this all out and am no longer sure which bits above relate to 32-bit and which to 64-bit code. On 32-bit arrays are indexed by signed 32-bit whether you call that int or long. It still seems to me this hinges on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100477
12-12-2024

For the life of me I cannot find out which warning this actually is. So, which warning to locally disable to get this built. The error appears even without any -W... on the command line. If the source is compiled with -O2, and I use a value > ptrdif for malloc length, I get the warning. Disabling all warnings with -w makes the error go away, but then I tried without success to find and re-enable the particular warning that switches this behavior. (But I am not even sure once warnings are disabled with -w that I then can enable specific warnings).
12-12-2024

[~dholmes] I dug a bit deeper. I can reproduce the problem on both 32-bit and 64-bit with a minimal program (just the giant_string function) if the malloc'ed len is larger than ptrdiff. So, for 64-bit, larger than LONG_MAX. While in theory this should be possible, GCC seems to have inbuilt warnings for this that hit on malloc, memset and the memory store. Your diff does not work for me, I get the same warnings. I get warnings however I try the array write, even if I use a temp pointer. I think the point here is that gcc detects us using something of size_t/2, which is usually wrong, so the warning is usually right. The fix may be to use mmap instead. Either that, or to disable the warning. Or to disable the test for 32-bit. "I think the array warnings are legitimate because the type of an array index is int." I don't what you mean by that. The array index type here is size_t. And you should be able to use long int on 64-bit as array index without a problem.
12-12-2024

Still getting this error when building 32bit (wanted to test my new changes with 32bit but it seems not even to compile) : test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:51:11: error: argument 1 value ‘2147483650’ exceeds maximum object size 2147483647 [-Werror=alloc-size-larger-than=] char* c_name = malloc(len * sizeof(char)); ^~~~~~ In file included from test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:26:0: /usr/include/stdlib.h:539:14: note: in a call to allocation function ‘malloc’ declared here extern void *malloc (size_t __size) __THROW __attribute_malloc__ ^~~~~~ test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:53:9: error: ‘memset’: specified size 2147483649 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=] memset(c_name, 'Y', len - 1); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ So I would say the Linux 32bit port is more or less dead and can#t be tested any more?
23-10-2024

Locally I get other warnings too: In function 'giant_string', inlined from 'Java_NoClassDefFoundErrorTest_tryCallDefineClass' at /scratch/users/daholme/jdk-dev4.git/open/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:61:20: /scratch/users/daholme/jdk-dev4.git/open/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:54:25: error: array subscript -2147483647 is outside array bounds of 'char[2147483647]' [-Werror=array-bounds=] 54 | c_name[len - 1] = '\0'; | ~~~~~~~~~~~~~~~~^~~~~~ /scratch/users/daholme/jdk-dev4.git/open/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:51:20: note: at offset -2147483647 into object of size 2147483647 allocated by 'malloc' 51 | char* c_name = malloc(len * sizeof(char)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ /scratch/users/daholme/jdk-dev4.git/open/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:53:9: error: 'memset' writing 18446744071562067969 bytes into a region of size 2147483647 [-Werror=stringop-overflow=] 53 | memset(c_name, 'Y', len - 1); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /scratch/users/daholme/jdk-dev4.git/open/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c:51:20: note: destination object of size 2147483647 allocated by 'malloc' 51 | char* c_name = malloc(len * sizeof(char)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ I think the array warnings are legitimate because the type of an array index is int. Not sure why this isn't flagged on 64-bit ?? Anyway this fix should be applied: diff --git a/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c b/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c index 023f299a5d4..334974ae21d 100644 --- a/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c +++ b/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c @@ -51,7 +51,7 @@ static char* giant_string() { char* c_name = malloc(len * sizeof(char)); if (c_name != NULL) { memset(c_name, 'Y', len - 1); - c_name[len - 1] = '\0'; + *(c_name + len - 1) = '\0'; } return c_name; }
03-09-2024

The more I look at this the less sense it makes. As Thomas notes the claimed amount being written is a 64-bit sign extended version of the actual 32-bit unsigned length. But we are on a 32-bit system so no 64-bit value should be involved here at all. gcc is just broken IMO.
03-09-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/20809 Date: 2024-09-02 09:59:54 +0000
02-09-2024

Except the test is not 64-bit only ...
02-09-2024

Does GHA not test this? I did a GHA run: https://github.com/dholmes-ora/jdk/actions/runs/10591461749 I think this error may relate to this reported issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100477 where it seems the fact it takes a size_t is not relevant to the warning, which is based around checks against `PTRDIFF_MAX - 1`. I think excluding the file from 32-bit builds is best, as you suggested. Thanks
02-09-2024

This is the preprocessed output: ``` static char* giant_string() { size_t len = ((size_t)0x7fffffff) + 3; char* c_name = malloc(len * sizeof(char)); if (c_name != # 52 "/shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c" 3 4 ((void *)0) # 52 "/shared/projects/openjdk/jdk-jdk/source/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c" ) { memset(c_name, 'Y', len - 1); c_name[len - 1] = '\0'; } return c_name; } ``` I even double-checked size_t, and it is "unsigned int" as expected. Both malloc and memset take size_t. size_t len evaluates to 0x80000002. len - 1 is 0x80000001. 18446744071562067969 is, interestingly, FFFFFFFF80000001₁₆ . So, GCC behaves as if we were to pass an int literal of 0x80000001 (negative) to memset, and as if memset were to take a 64bit size. And it would then sign extend? I have no idea how GCC thinks the
30-08-2024