-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed
Labels
bugObserved behavior contradicts documented or intended behaviorObserved behavior contradicts documented or intended behavioros-linuxLinuxLinux
Milestone
Description
Zig Version
0.12.0-dev.244+f4c9e19bc
Steps to Reproduce and Observed Behavior
When linking glibc, the fstatat error seems to get lost, and some other error is returned from getErrno/c._errno().* instead (seen ESUCCESS and EEXIST, but expected ENOENT).
Test code:
const std = @import("std");
pub fn main() !void {
{
// this gives a bogus errno
var stat = std.mem.zeroes(std.c.Stat);
const rc = std.c.fstatat64(std.os.AT.FDCWD, "test_file_that_doesnt_exist", &stat, 0);
const err = std.c.getErrno(rc);
std.debug.print("glibc: {} {}\n", .{ rc, err });
}
{
// this gives the correct errno
var stat = std.mem.zeroes(std.os.linux.Stat);
const rc = std.os.linux.fstatat(std.os.AT.FDCWD, "test_file_that_doesnt_exist", &stat, 0);
const err = std.os.linux.getErrno(rc);
std.debug.print("syscall: {} {}\n", .{ rc, err });
}
}built with:
zig build-exe fstatat.zig -lc -target x86_64-linux-gnu
output:
glibc: -1 os.linux.errno.generic.E.SUCCESS
syscall: 18446744073709551614 os.linux.errno.generic.E.NOENT
commented strace with only the relevant parts:
// std.c.fstatat64
newfstatat(AT_FDCWD, "test_file_that_doesnt_exist", 0x7ffc3675cfd8, 0) = -1 ENOENT (No such file or directory)
gettid() = 117441
write(2, "SUCCESS", 7SUCCESS) = 7
// std.os.linux.fstatat
newfstatat(AT_FDCWD, "test_file_that_doesnt_exist", 0x7ffc3675d0f8, 0) = -1 ENOENT (No such file or directory)
write(2, "NOENT", 5NOENT) = 5
(so both syscalls are the same, but somehow the glibc version doesn't
The same problem exists in the equivalent C code compiled by Zig:
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
struct stat statbuf;
int rc = fstatat(AT_FDCWD, "test_file_that_doesnt_exist", &statbuf, 0);
printf("%d %d\n", rc, errno);
}$ zig build-exe fstatat.c -lc -target x86_64-linux-gnu -femit-bin=fstatat-c
$ ./fstatat-c
-1 0
$ ldd ./fstatat-c
linux-vdso.so.1 (0x00007ffed69c3000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f77c7504000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f77c7312000)
/lib64/ld-linux-x86-64.so.2 (0x00007f77c754e000)but the same C code works as expected when compiled with clang directly:
$ clang fstatat.c -o fstatat-clang
$ ./fstatat-clang
-1 2
$ ldd ./fstatat-clang
linux-vdso.so.1 (0x00007ffd5dbc1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc74afa3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc74b1c1000)(2 is ENOENT)
The strace between the Zig-compiled C version and the Clang-compiled C version are the same:
// zig compiled
newfstatat(AT_FDCWD, "test_file_that_doesnt_exist", 0x7ffd8b185998, 0) = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
brk(NULL) = 0x855000
brk(0x876000) = 0x876000
write(1, "-1 0\n", 5-1 0
) = 5
// clang compiled
newfstatat(AT_FDCWD, "test_file_that_doesnt_exist", 0x7fff3985d0b0, 0) = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
brk(NULL) = 0x558433e61000
brk(0x558433e82000) = 0x558433e82000
write(1, "-1 2\n", 5-1 2
) = 5
Expected Behavior
fstatat errors to be accurately returned when linking glibc
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugObserved behavior contradicts documented or intended behaviorObserved behavior contradicts documented or intended behavioros-linuxLinuxLinux