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.

Reply via email to