On Mon, Jan 27, 2025, at 15:19, Jérémy Lal wrote:
> Hi,
>
> as discussed in
> https://github.com/libuv/libuv/issues/4678
>
> and associated build failures 
> https://buildd.debian.org/status/package.php?p=libuv1&suite=experimental
>
> It seems that gcc is doing something wrong with the offset parameter of 
> preadv, pwritev.
> The same problem happens with optimization levels 0, 1, 2.
>
> The call is made at
> https://salsa.debian.org/debian/libuv1/-/blob/debian/sid/src/unix/fs.c?ref_type=heads#L494
>
> To reproduce, just dpkg-buildpackage from
> dget -xu 
> https://deb.debian.org/debian/pool/main/libu/libuv1/libuv1_1.49.2-1.dsc
>
> I'd be surprised if it concerns only libuv !
> Please have a look, because the libuv maintainers already tried their best.

My strong guess is that this is caused by the implied 64-bit
off_t after the time64 conversion. On i386, the file is
likely still built with a 32-bit off_t.

In the source line

    p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev");

the uv__preadv_or_pwritev() function looks up the preadv() or
pwritev() symbols in glibc, but those expect a 32-bit ("long")
off_t, unlike preadv64() and pwritev64().

It appears that  https://github.com/libuv/libuv/issues/4532
attempted to address the issue, but completely misunderstood
the problem, as this was a bug in libuv, not in gcc.

Ideally the library should avoid using dlsym() here, since
that makes it unportable. If it can't be avoided, it could
try to do something like

   if ((sizeof(long)< sizeof(off_t))
            p = dlsym(RTLD_DEFAULT, is_pread ? "preadv64" : "pwritev64");
   else
            p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev");

This in turn makes it less portable to non-glibc
implementations like musl.

     Arnd

Reply via email to