Originally spotted as tools/jar/ReproducibleJar.java failure on x86_32, see JDK-8279453.
Reproduced with standalone jdk/bin/jar installation all the way back to 8u, using attached JAR.
$ rm -rf outer; ./build/linux-x86-server-fastdebug/images/jdk/bin/jar xvf 8279444.jar; stat outer
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: outer/
created: outer/inner/
inflated: outer/inner/foo.txt
File: outer
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd00h/64768d Inode: 88233545 Links: 3
Access: (0775/drwxrwxr-x) Uid: ( 1000/ shade) Gid: ( 1000/ shade)
Access: 2022-01-04 16:43:13.936388000 +0100
Modify: 1963-11-25 17:31:42.000000000 +0100
Change: 2022-01-04 16:43:13.936388034 +0100
Birth: -
$ rm -rf outer; ./build/linux-x86_64-server-fastdebug/images/jdk/bin/jar xvf 8279444.jar; stat outer
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: outer/
created: outer/inner/
inflated: outer/inner/foo.txt
File: outer
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd00h/64768d Inode: 88233545 Links: 3
Access: (0775/drwxrwxr-x) Uid: ( 1000/ shade) Gid: ( 1000/ shade)
Access: 2022-01-04 16:43:17.740488000 +0100
Modify: 2099-12-31 23:59:58.000000000 +0100
Change: 2022-01-04 16:43:17.740488841 +0100
Birth: -
Note bad "Modify" date in x86_32 case, and good time in x86_64 case.
I believe this is 2038 problem due to overflow during preparation for utimes call. This assert fails on x86_32, but passes on x86_64:
diff --git a/src/java.base/unix/native/libjava/UnixFileSystem_md.c b/src/java.base/unix/native/libjava/UnixFileSystem_md.c
index 7c23aaa567c..7b4fa9b198e 100644
--- a/src/java.base/unix/native/libjava/UnixFileSystem_md.c
+++ b/src/java.base/unix/native/libjava/UnixFileSystem_md.c
@@ -427,7 +427,9 @@ Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
tv[0].tv_usec = sb.st_atim.tv_nsec / 1000;
#endif
/* Change last-modified time */
- tv[1].tv_sec = time / 1000;
+ jlong t = time / 1000;
+ tv[1].tv_sec = t;
+ assert(tv[1].tv_sec == t);
tv[1].tv_usec = (time % 1000) * 1000;
if (utimes(path, tv) == 0)
I see that glibc started year2038 workaround work with extending tv_sec to time64_t, first batch available in glibc 2.34 (which is rather recent):
https://sourceware.org/glibc/wiki/Y2038ProofnessDesign#struct_timespec
https://sourceware.org/git/?p=glibc.git;a=commit;h=bdc4782744df73a8c0559985c54b5b6b9c7a4a74
https://sourceware.org/pipermail/libc-alpha/2021-August/129718.html
"* Add support for 64-bit time_t on configurations like x86 where time_t
is traditionally 32-bit. Although time_t still defaults to 32-bit on
these configurations, this default may change in future versions.
This is enabled with the _TIME_BITS preprocessor macro set to 64 and is
only supported when LFS (_FILE_OFFSET_BITS=64) is also enabled. It is
only enabled for Linux and the full support requires a minimum kernel
version of 5.1."
But it does not look like a complete support is there yet, so this issue looks unsolvable at this time.
Reproduced with standalone jdk/bin/jar installation all the way back to 8u, using attached JAR.
$ rm -rf outer; ./build/linux-x86-server-fastdebug/images/jdk/bin/jar xvf 8279444.jar; stat outer
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: outer/
created: outer/inner/
inflated: outer/inner/foo.txt
File: outer
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd00h/64768d Inode: 88233545 Links: 3
Access: (0775/drwxrwxr-x) Uid: ( 1000/ shade) Gid: ( 1000/ shade)
Access: 2022-01-04 16:43:13.936388000 +0100
Modify: 1963-11-25 17:31:42.000000000 +0100
Change: 2022-01-04 16:43:13.936388034 +0100
Birth: -
$ rm -rf outer; ./build/linux-x86_64-server-fastdebug/images/jdk/bin/jar xvf 8279444.jar; stat outer
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: outer/
created: outer/inner/
inflated: outer/inner/foo.txt
File: outer
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd00h/64768d Inode: 88233545 Links: 3
Access: (0775/drwxrwxr-x) Uid: ( 1000/ shade) Gid: ( 1000/ shade)
Access: 2022-01-04 16:43:17.740488000 +0100
Modify: 2099-12-31 23:59:58.000000000 +0100
Change: 2022-01-04 16:43:17.740488841 +0100
Birth: -
Note bad "Modify" date in x86_32 case, and good time in x86_64 case.
I believe this is 2038 problem due to overflow during preparation for utimes call. This assert fails on x86_32, but passes on x86_64:
diff --git a/src/java.base/unix/native/libjava/UnixFileSystem_md.c b/src/java.base/unix/native/libjava/UnixFileSystem_md.c
index 7c23aaa567c..7b4fa9b198e 100644
--- a/src/java.base/unix/native/libjava/UnixFileSystem_md.c
+++ b/src/java.base/unix/native/libjava/UnixFileSystem_md.c
@@ -427,7 +427,9 @@ Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
tv[0].tv_usec = sb.st_atim.tv_nsec / 1000;
#endif
/* Change last-modified time */
- tv[1].tv_sec = time / 1000;
+ jlong t = time / 1000;
+ tv[1].tv_sec = t;
+ assert(tv[1].tv_sec == t);
tv[1].tv_usec = (time % 1000) * 1000;
if (utimes(path, tv) == 0)
I see that glibc started year2038 workaround work with extending tv_sec to time64_t, first batch available in glibc 2.34 (which is rather recent):
https://sourceware.org/glibc/wiki/Y2038ProofnessDesign#struct_timespec
https://sourceware.org/git/?p=glibc.git;a=commit;h=bdc4782744df73a8c0559985c54b5b6b9c7a4a74
https://sourceware.org/pipermail/libc-alpha/2021-August/129718.html
"* Add support for 64-bit time_t on configurations like x86 where time_t
is traditionally 32-bit. Although time_t still defaults to 32-bit on
these configurations, this default may change in future versions.
This is enabled with the _TIME_BITS preprocessor macro set to 64 and is
only supported when LFS (_FILE_OFFSET_BITS=64) is also enabled. It is
only enabled for Linux and the full support requires a minimum kernel
version of 5.1."
But it does not look like a complete support is there yet, so this issue looks unsolvable at this time.
- relates to
-
JDK-8279453 Disable tools/jar/ReproducibleJar.java on 32-bit platforms
-
- Resolved
-