Bug 31510 - Wrong type for timeval.tv_usec on 32-bit archs with _TIME_BITS=64
Summary: Wrong type for timeval.tv_usec on 32-bit archs with _TIME_BITS=64
Status: UNCONFIRMED
Alias: None
Product: glibc
Classification: Unclassified
Component: time (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-19 11:24 UTC by Simon Chopin
Modified: 2024-03-20 13:48 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Chopin 2024-03-19 11:24:14 UTC
POSIX documents struct timeval as follows:

struct timeval {
    time_t      tv_sec;         /* seconds */
    suseconds_t tv_usec;        /* microseconds */
};
Since bdc4782744df73a8c0559985c54b5b6b9c7a4a74 ("y2038: Add __USE_TIME_BITS64 support for struct timeval") tv_usec can have __suseconds64_t when using 64-bit time, however suseconds_t is unconditionally typedefed to __suseconds_t.

That leads to the following:

ubuntu@mantic-armhf:~$ cat test.c
#include <sys/time.h>
#include <stdio.h>
#include <assert.h>

int main(void)
{
        struct timeval tv;
        printf("tv_usec: %d, suseconds_t: %d\n", sizeof(tv.tv_usec), sizeof(suseconds_t));
        assert(sizeof(tv.tv_usec) == sizeof(suseconds_t));
        return 0;
}
ubuntu@mantic-armhf:~$ gcc test.c && ./a.out
tv_usec: 4, suseconds_t: 4
ubuntu@mantic-armhf:~$ gcc -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 test.c && ./a.out
tv_usec: 8, suseconds_t: 4
a.out: test.c:9: main: Assertion `sizeof(tv.tv_usec) == sizeof(suseconds_t)' failed.
Aborted (core dumped)

We noticed this when running the conformance tests on Ubuntu Noble, where we've set _TIME_BITS=64 in the default GCC flags as part of the ongoing t64 transition.
Comment 1 Adhemerval Zanella 2024-03-19 12:15:18 UTC
Yes, this was an overlook which I am not fully sure how to handle without breaking 'current' 64 time ABI. Maybe we can follow the timespec one, time/bits/types/struct_timespec.h, used 32 bit suseconds_t and add proper paddings depending of the endianess.
Comment 2 Joseph Myers 2024-03-19 20:21:42 UTC
Shouldn't we fix how suseconds_t is defined in glibc in the 64-bit time case? It's not as if any interfaces in glibc use suseconds_t other than as part of struct timeval (though we should still warn in NEWS about potential compatibility issues for any interfaces using suseconds_t in third-party libraries).
Comment 3 Joseph Myers 2024-03-19 20:22:41 UTC
(Not that suseconds_t *needs* to be 64-bit to store values from 0 to 999999, but there's nothing wrong with it being 64-bit either, it just needs to agree with the type of tv_usec.)
Comment 4 Adhemerval Zanella 2024-03-20 12:27:41 UTC
(In reply to Joseph Myers from comment #2)
> Shouldn't we fix how suseconds_t is defined in glibc in the 64-bit time
> case? It's not as if any interfaces in glibc use suseconds_t other than as
> part of struct timeval (though we should still warn in NEWS about potential
> compatibility issues for any interfaces using suseconds_t in third-party
> libraries).

That's why I am not fully sure which would be the best way, since this strictly is an ABI break.  

At least using the timespec trick to keep the type as currently defined should not cause any issue (since the type holds all potential values), and it should be back-portable.
Comment 5 Simon Chopin 2024-03-20 13:48:49 UTC
FWIW, we've actually seen at least one package seemingly failing to build because of this issue: 
https://launchpadlibrarian.net/720254657/buildlog_ubuntu-noble-armhf.libflorist_2022.0.1~20220616-5_BUILDING.txt.gz

> posix-c.ads:876:07: error: size for "suseconds_t" too small, minimum allowed is 64

I didn't dig into what exactly they're doing there.