ChezScheme
ChezScheme copied to clipboard
32-bit targets have Y2038 bug, hard-code time_t_bits==32
It's come to my attention through Alpine Linux that there are build errors on musl libc 1.2.x 32-bit archs, where time_t is now 64-bit. Can the 32-bit targets be made to pull the definition of time_t from the system headers, or are these targets defining ChezScheme ABIs that have to be preserved for compatibility with external binaries? If the latter is the case, can new targets be added for 32-bit archs with 64-bit time_t, since any ABI with 32-bit time_t is pretty much EOL now?
From a cursory look through the code, I think you should be able to eliminate the time_t_bits definition and instead use sizeof(time_t) whenever necessary in the C code. Beware of the Sinteger32_value call in S_condition_wait, which seems to be a bug in 64-bit systems today.
It doesn't matter which is used in the C code. time_t_bits is defined (as time-t-bits) in the various s directory machine-type def files, along with int_bits (int-bits), long_bits (long-bits), etc., as they must be for cross compilation of foreign-interface code to work correctly. A mismatch between time_t_bits and sizeof(time_t) will be caught by idiot_checks in scheme.c. Said another way, if idiot_checks doesn't catch it, the C object code agrees with the Scheme object code. Both might be wrong, in which case the out-of-date .def file needs to be updated and the Scheme and C code recompiled.
@burgerrg, are you concerned with the call to Sinteger32_value used to extract the number of seconds from the time record? It should probably be changed, but the net effect seems to be to limit the range of condition_wait time values to a fairly reasonable sounding 68 years or so.
@dybvig, so what needs to be done to make this work? time_t is now 64-bit on all our archs.
Safest would be this: Find a machine upon which Chez Scheme builds successfully, e.g., a 64-bit linux VM or mac laptop. Edit the definition of time-t-bits in s/i3le.def (nonthreaded) and s/ti3le.def (threaded), run 'configure' and 'make bootfiles', then copy s/i3le.def, s/ti3le.def, boot/i3le/, and boot/ti3le/ to your 32-bit Linux system. Then you should be able to configure and make successfully.
You might also have success just editing the setting of time_t_bits in s/i3le.def, s/ti3le.def, boot/i3le/equates.h, and boot/ti3le/equates.h and running configure and make all on your 32-bit Linux system.
I don't know if the world is ready for time-t-bits to be 32 in the committed i3le.def and ti3le.def; there are still a lot of older Linux distributions in production use. Since we start with pre-built boot and header files, configure time is too late to determine the setting, so we have to set such things in the .def file. I'm not keen on creating a second set of .def files for the new value of time_t, but that's always a possibility.
@dybvig, yes, I'm concerned that s_thread_cond_timedwait can be passed a time-utc that exceeds the 32-bit long. The cond_timedwait procedure takes both absolute and relative time.
Ah, indeed. I'll work on a fix for that. Thanks!
I've addressed the S_condition_wait issue in commit 95280ad. While I was in the code, I changed the nanosecond to millisecond conversion to round rather than truncate. @burgerrg, I don't have a setup to test under Windows, and appears to me that Travis builds aren't running, so please check to make sure the threaded version compiles and runs under Windows if you get a chance.
@dybvig, I'll test the Windows threaded version this morning. Thanks for updating this!
@dybvig, the Windows threaded version compiles & runs under Windows with no problems.
All the Windows versions pass the mats that Travis CI runs.
I think you will have to use a separate target definition for Linux i386 with a 64-bit time_t. Both ABI variants will exist for a long time in parallel. glibc is still 32-bit-only and may remain so on i386, only musl has switched.
Has there been any progress on this? My understanding is that with the changes made to s_thread_cond_timedwait it should now be possible to infer the size of time_t using sizeof(time_t) as suggested in https://github.com/cisco/ChezScheme/issues/527#issuecomment-674970178, no?
As Kent explained in the immediately following comment, the problem is not figuring out what size the C compiler thinks time_t is from inside C code, it's that the size has to be defined for use in Scheme (see, e.g., i3le.def) and the two values must match.
I tend to agree with the last comment on this issue from 2020: an ABI-incompatible libc might be best supported as a different machine type. I think there's a reasonable argument for attempting to figure out the "right" value during configure, but that path seems fragile (e.g., the choice of libc could be changed at build time, i.e., after configure).
e.g., the choice of libc could be changed at build time, i.e., after configure
The "choice of libc" is the target. There's no plausible way you support it changing after configure. That's like saying it should work for someone to configure for Linux then decide they want to build for Windows instead.
No, I'm pretty sure that this glibc documentation says that you can compile against a different libc by setting CFLAGS and LDFLAGS, which should work fine with the Makefile that I have sitting in my workarea after running configure. Maybe you are thinking the Chez Scheme configure script is more complicated than it actually is. It is decidedly not an autoconf/autotools style configure script. (I'm not saying this is a good idea, just that I think it's possible.)
No, I'm pretty sure that this glibc documentation ...
does not govern what you can do with non-glibc implementations, and no, you absolutely can't do that.
If you just mean "a different build/version of glibc", that's probably true, but then it will not differ (for the same target configuration).
It turns out that time-t-bits is no longer needed and has been removed (#770). So, you can compile and link to get a suitable time_t for the Chez Scheme kernel, and it doesn't need different boot files or a new machine type.