https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89447
Bug ID: 89447 Summary: libgo largefile support is incomplete and inconsistent Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: go Assignee: ian at airs dot com Reporter: ro at gcc dot gnu.org CC: cmang at google dot com Target Milestone: --- Target: *-*-solaris2.* When investigating the remaining libgo testsuite failures on Solaris, I came across a group with a common root cause. E.g. --- FAIL: TestSharedLibName (0.00s) build_test.go:182: not owner build_test.go:182: not owner FAIL /vol/gcc/src/hg/trunk/local/libgo/testsuite/gotest[685]: wait: 8433: Terminated FAIL: cmd/go/internal/work The failure is from a call to os.RemoveAll. It turns out that removeAllFrom returns early because statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR which is weird given that tmpGopath *is* a directory. I find that fstatat is called Thread 15 hit Breakpoint 1, 0xfdb71b7c in fstatat () from /lib/libc.so.1 (gdb) where #0 0xfdb71b7c in fstatat () from /lib/libc.so.1 #1 0xfe7c2da8 in internal..z2fsyscall..z2funix.Fstatat (dirfd=dirfd@entry=3, path=..., stat=stat@entry=0x6ca280, flags=flags@entry=4096) at /vol/gcc/src/hg/trunk/local/libgo/go/internal/syscall/unix/at.go:70 #2 0xfe947680 in os.removeAllFrom (parent=parent@entry=0xd050060, path=...) at /vol/gcc/src/hg/trunk/local/libgo/go/os/removeall_at.go:66 #3 0xfe947e04 in os.RemoveAll ( path=<error reading variable: Cannot access memory at address 0x5>) at /vol/gcc/src/hg/trunk/local/libgo/go/os/removeall_at.go:48 which seems broken: given that this is a 32-bit program and sysinfo.go was built with -D_FILE_OFFSET_BITS=64 (and thus the struct that is passed in is actually struct stat64), this should be a call to fstatat64 instead. And indeed the contents of Stat_t is off: $4 = {Dev = 4292345858, st_pad1 = {0, 0, 0}, Ino = 2669371652487266752, Mode = 3, Nlink = 2110, Uid = 1004, Gid = 4294967295, Rdev = 0, st_pad2 = { 0, 177}, Size = 6660097377203678494, Atim = {Sec = 1550674759, Nsec = 566076105}, Mtim = {Sec = 1550674759, Nsec = 566076105}, Ctim = { Sec = 8192, Nsec = 16}, Blksize = 1953329254, Blocks = 0, st_fstype = '\000' <repeats 15 times>, st_pad4 = {0, 0, 0, 0, 0, 0, 0, 0}} with Mode = 3 and Nlink = 2110 (which is really Uid!). It turns out that there are more instances of the same problem: looking for references to functions that have unused largefile equivalents in libc, I found creat, getdents, mmap, openat, sendfile, and mkstemp (x86 only). The attached initial patch fixes many of those by adding largefile equivalents. Afterwards, only calls to mmap (from closures.o, i.e. libffi_convenience.a and mem_gccgo.go) and mkstemp (again from closures.o) are left. ISTM that they are ok, given that they don't use the Offset_t etc. types from sysinfo.go, but the underlying 32-bit ones. With the exception of getdents (which is Solaris-specific anyway), all those largefile functions are present on Linux, too, but I suspect the build tags aren't right yet. Bootstrapped on i386-pc-solaris2.11, sparc-sun-solaris2.11, and x86_64-pc-linux-gnu (both multilibs each). No regressions on Linux/x86_64 and many related testsuite failures in both libgo and gotools are gone on Solaris.