diff mbox

libgo patch committed: Update to current version of Go library

Message ID CAFULd4YwYOFh_UEKDULiB4DF56LOH8Fdzz4ybC1n-e4d7e-dpg@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Feb. 8, 2013, 3:23 p.m. UTC
On Fri, Feb 8, 2013 at 4:02 PM, Ian Lance Taylor <iant@google.com> wrote:

>>>> I did hit one new error that seems related:
>>>>
>>>> --- FAIL: TestChtimes (0.00 seconds)
>>>> os_test.go:681:         AccessTime didn't go backwards;
>>>> was={63495872497 0 47130825733376}, after={63495872497 0
>>>> 47130825733376}
>>>> os_test.go:685:         ModTime didn't go backwards; was={63495872497
>>>> 0 47130825733376}, after={63495872497 0 47130825733376}
>>>> FAIL
>>>> FAIL: os
>>>
>>> Something has gone wrong in the file
>>> libgo/go/syscall/libcall_linux_utimesnano.go.  The function in that
>>> file will try utimensat.  On your system that should return ENOSYS.
>>> In that case the function should convert the times and call utimes.
>>> The code looks OK to me but there may be something wrong with it.  It
>>> looks like the file times didn't change at all.
>>
>> From the strace -f, it looks that utimes is not called at all in
>> between two relevant stats:
>
> Strange.  What I would expect to happen is that the function in
> libcall_linux_utimesnano.go will call utimensat.  Since your system
> does not have that function, that will call the stub routine in
> libgo/runtime/go-nosys.c, which will return -1 with errno set to
> ENOSYS.  The code in libcall_linux_utimensnano.go will see the ENOSYS
> error and continue on to call utime.  Clearly something is going wrong
> in that sequence, but I don't know what.

Somwhow expected, following "patch" makes test to pass:

--cut here--
added to Linux
        // in 2.6.22, Released, 8 July 2007) then fall back to utimes
        var tv [2]Timeval
--cut here--

11491 stat("/tmp/_Go_TestChtimes581938713", {st_mode=S_IFREG|0600,
st_size=13, ...}) = 0
11491 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
11491 utimes("/tmp/_Go_TestChtimes581938713", {{1360336212, 0},
{1360336212, 0}}) = 0
11491 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
11491 stat("/tmp/_Go_TestChtimes581938713", {st_mode=S_IFREG|0600,
st_size=13, ...}) = 0

It looks to me that gcc miscompiles this part for some reason...?

Uros.

Comments

Ian Lance Taylor Feb. 8, 2013, 4:21 p.m. UTC | #1
On Fri, Feb 8, 2013 at 7:23 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Fri, Feb 8, 2013 at 4:02 PM, Ian Lance Taylor <iant@google.com> wrote:
>
>>>>> I did hit one new error that seems related:
>>>>>
>>>>> --- FAIL: TestChtimes (0.00 seconds)
>>>>> os_test.go:681:         AccessTime didn't go backwards;
>>>>> was={63495872497 0 47130825733376}, after={63495872497 0
>>>>> 47130825733376}
>>>>> os_test.go:685:         ModTime didn't go backwards; was={63495872497
>>>>> 0 47130825733376}, after={63495872497 0 47130825733376}
>>>>> FAIL
>>>>> FAIL: os
>>>>
>>>> Something has gone wrong in the file
>>>> libgo/go/syscall/libcall_linux_utimesnano.go.  The function in that
>>>> file will try utimensat.  On your system that should return ENOSYS.
>>>> In that case the function should convert the times and call utimes.
>>>> The code looks OK to me but there may be something wrong with it.  It
>>>> looks like the file times didn't change at all.
>>>
>>> From the strace -f, it looks that utimes is not called at all in
>>> between two relevant stats:
>>
>> Strange.  What I would expect to happen is that the function in
>> libcall_linux_utimesnano.go will call utimensat.  Since your system
>> does not have that function, that will call the stub routine in
>> libgo/runtime/go-nosys.c, which will return -1 with errno set to
>> ENOSYS.  The code in libcall_linux_utimensnano.go will see the ENOSYS
>> error and continue on to call utime.  Clearly something is going wrong
>> in that sequence, but I don't know what.
>
> Somwhow expected, following "patch" makes test to pass:
>
> --cut here--
> Index: go/syscall/libcall_linux_utimesnano.go
> ===================================================================
> --- go/syscall/libcall_linux_utimesnano.go      (revision 195879)
> +++ go/syscall/libcall_linux_utimesnano.go      (working copy)
> @@ -14,10 +14,10 @@
>         if len(ts) != 2 {
>                 return EINVAL
>         }
> -       err = utimensat(_AT_FDCWD, path,
> (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
> -       if err != ENOSYS {
> -               return err
> -       }
> +//     err = utimensat(_AT_FDCWD, path,
> (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
> +//     if err != ENOSYS {
> +//             return err
> +//     }
>         // If the utimensat syscall isn't available (utimensat was
> added to Linux
>         // in 2.6.22, Released, 8 July 2007) then fall back to utimes
>         var tv [2]Timeval
> --cut here--
>
> 11491 stat("/tmp/_Go_TestChtimes581938713", {st_mode=S_IFREG|0600,
> st_size=13, ...}) = 0
> 11491 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
> 11491 utimes("/tmp/_Go_TestChtimes581938713", {{1360336212, 0},
> {1360336212, 0}}) = 0
> 11491 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
> 11491 stat("/tmp/_Go_TestChtimes581938713", {st_mode=S_IFREG|0600,
> st_size=13, ...}) = 0
>
> It looks to me that gcc miscompiles this part for some reason...?

A miscompilation seems fairly unlikely.  I expect it's something very
obvious, I'm just not seeing it.  Can you verify that the code reaches
the stub definition of utimensat in libgo/runtime/go-nosys.c?

In fact, maybe if you just send me the test executable it will fail on
my system.  Seems worth a try.

Ian
Uros Bizjak Feb. 8, 2013, 4:48 p.m. UTC | #2
On Fri, Feb 8, 2013 at 5:21 PM, Ian Lance Taylor <iant@google.com> wrote:
> On Fri, Feb 8, 2013 at 7:23 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Fri, Feb 8, 2013 at 4:02 PM, Ian Lance Taylor <iant@google.com> wrote:
>>
>>>>>> I did hit one new error that seems related:
>>>>>>
>>>>>> --- FAIL: TestChtimes (0.00 seconds)
>>>>>> os_test.go:681:         AccessTime didn't go backwards;
>>>>>> was={63495872497 0 47130825733376}, after={63495872497 0
>>>>>> 47130825733376}
>>>>>> os_test.go:685:         ModTime didn't go backwards; was={63495872497
>>>>>> 0 47130825733376}, after={63495872497 0 47130825733376}
>>>>>> FAIL
>>>>>> FAIL: os
>>>>>
>>>>> Something has gone wrong in the file
>>>>> libgo/go/syscall/libcall_linux_utimesnano.go.  The function in that
>>>>> file will try utimensat.  On your system that should return ENOSYS.
>>>>> In that case the function should convert the times and call utimes.
>>>>> The code looks OK to me but there may be something wrong with it.  It
>>>>> looks like the file times didn't change at all.
>>>>
>>>> From the strace -f, it looks that utimes is not called at all in
>>>> between two relevant stats:
>>>
>>> Strange.  What I would expect to happen is that the function in
>>> libcall_linux_utimesnano.go will call utimensat.  Since your system
>>> does not have that function, that will call the stub routine in
>>> libgo/runtime/go-nosys.c, which will return -1 with errno set to
>>> ENOSYS.  The code in libcall_linux_utimensnano.go will see the ENOSYS
>>> error and continue on to call utime.  Clearly something is going wrong
>>> in that sequence, but I don't know what.
>>
>> Somwhow expected, following "patch" makes test to pass:
>>
>> --cut here--
>> Index: go/syscall/libcall_linux_utimesnano.go
>> ===================================================================
>> --- go/syscall/libcall_linux_utimesnano.go      (revision 195879)
>> +++ go/syscall/libcall_linux_utimesnano.go      (working copy)
>> @@ -14,10 +14,10 @@
>>         if len(ts) != 2 {
>>                 return EINVAL
>>         }
>> -       err = utimensat(_AT_FDCWD, path,
>> (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
>> -       if err != ENOSYS {
>> -               return err
>> -       }
>> +//     err = utimensat(_AT_FDCWD, path,
>> (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
>> +//     if err != ENOSYS {
>> +//             return err
>> +//     }
>>         // If the utimensat syscall isn't available (utimensat was
>> added to Linux
>>         // in 2.6.22, Released, 8 July 2007) then fall back to utimes
>>         var tv [2]Timeval
>> --cut here--
>>
>> 11491 stat("/tmp/_Go_TestChtimes581938713", {st_mode=S_IFREG|0600,
>> st_size=13, ...}) = 0
>> 11491 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
>> 11491 utimes("/tmp/_Go_TestChtimes581938713", {{1360336212, 0},
>> {1360336212, 0}}) = 0
>> 11491 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
>> 11491 stat("/tmp/_Go_TestChtimes581938713", {st_mode=S_IFREG|0600,
>> st_size=13, ...}) = 0
>>
>> It looks to me that gcc miscompiles this part for some reason...?
>
> A miscompilation seems fairly unlikely.  I expect it's something very
> obvious, I'm just not seeing it.  Can you verify that the code reaches
> the stub definition of utimensat in libgo/runtime/go-nosys.c?

utimensat returns zero on CentOS. Following is gdb session:

Breakpoint 1, syscall.UtimesNano (path=..., ts.param=...) at
../../../gcc-svn/trunk/libgo/go/syscall/libcall_linux_utimesnano.go:13
13      func UtimesNano(path string, ts []Timespec) (err error) {
(gdb) n
14              if len(ts) != 2 {
(gdb) n
13      func UtimesNano(path string, ts []Timespec) (err error) {
(gdb) n
14              if len(ts) != 2 {
(gdb) n
17              err = utimensat(_AT_FDCWD, path,
(*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
(gdb) n
17              err = utimensat(_AT_FDCWD, path,
(*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
(gdb) n
18              if err != ENOSYS {
(gdb) p err
$1 = {__methods = 0x0, __object = 0x0}
(gdb) n
19                      return err
(gdb) n
29      }
(gdb) n
os.Chtimes (name=..., atime.param=..., mtime.param=...) at file_posix.go:162
162             return nil
(gdb) c
Continuing.
--- FAIL: TestChtimes (41.09 seconds)
os_test.go:681:         AccessTime didn't go backwards;
was={63495938759 0 46912511898976}, after={63495938759 0
46912511898976}
os_test.go:685:         ModTime didn't go backwards; was={63495938759
0 46912511898976}, after={63495938759 0 46912511898976}
FAIL

Uros.
Ian Lance Taylor Feb. 8, 2013, 4:53 p.m. UTC | #3
On Fri, Feb 8, 2013 at 8:48 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>
> utimensat returns zero on CentOS. Following is gdb session:

Thanks--can you do the same session but with "step" instead of "next"?

Ian
Uros Bizjak Feb. 8, 2013, 5:10 p.m. UTC | #4
On Fri, Feb 8, 2013 at 5:53 PM, Ian Lance Taylor <iant@google.com> wrote:
> On Fri, Feb 8, 2013 at 8:48 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>
>> utimensat returns zero on CentOS. Following is gdb session:
>
> Thanks--can you do the same session but with "step" instead of "next"?

I think I got the problem.

breakpoint at utimensat

(gdb) list
271     int
272     utimensat(int dirfd __attribute__ ((unused)),
273               const char *pathname __attribute__ ((unused)),
274               const struct timespec times[2] __attribute__ ((unused)),
275               int flags __attribute__ ((unused)))
276     {
277       errno = ENOSYS;
278       return -1;
279     }

Breakpoint 2, utimensat (dirfd=dirfd@entry=-100,
pathname=pathname@entry=0xc20064e000 "/tmp/_Go_TestChtimes925784001",
times=times@entry=0xc20064e0e0,
    flags=flags@entry=0) at ../../../gcc-svn/trunk/libgo/runtime/go-nosys.c:276
276     {
(gdb) fin
Run till exit from #0  utimensat (dirfd=dirfd@entry=-100,
pathname=pathname@entry=0xc20064e000 "/tmp/_Go_TestChtimes925784001",
    times=times@entry=0xc20064e0e0, flags=flags@entry=0) at
../../../gcc-svn/trunk/libgo/runtime/go-nosys.c:276
syscall.utimensat (dirfd=-100, flags=0, times=0xc20064e0e0, path=...)
at libcalls.go:2371
2371            if _r < 0 {
Value returned is $5 = -1

However, _r at call site is unsigned.

(gdb) p _r
$6 = 4294967295
(gdb) list
2366            }
2367            Entersyscall()
2368            _r := c_utimensat(int(dirfd), _p2, times, int(flags))
2369            var errno Errno
2370            setErrno := false
2371            if _r < 0 {
2372                    errno = GetErrno()
2373                    setErrno = true
2374            }
2375            Exitsyscall()

(gdb) n
2375            Exitsyscall()
(gdb) n
syscall.UtimesNano (path=..., ts.param=...) at
../../../gcc-svn/trunk/libgo/go/syscall/libcall_linux_utimesnano.go:18
18              if err != ENOSYS {
(gdb) li
13      func UtimesNano(path string, ts []Timespec) (err error) {
14              if len(ts) != 2 {
15                      return EINVAL
16              }
17              err = utimensat(_AT_FDCWD, path,
(*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
18              if err != ENOSYS {
19                      return err
20              }
21              // If the utimensat syscall isn't available (utimensat
was added to Linux
22              // in 2.6.22, Released, 8 July 2007) then fall back to utimes
(gdb) p err
$8 = {__methods = 0x0, __object = 0x0}

Uros.
diff mbox

Patch

Index: go/syscall/libcall_linux_utimesnano.go
===================================================================
--- go/syscall/libcall_linux_utimesnano.go      (revision 195879)
+++ go/syscall/libcall_linux_utimesnano.go      (working copy)
@@ -14,10 +14,10 @@ 
        if len(ts) != 2 {
                return EINVAL
        }
-       err = utimensat(_AT_FDCWD, path,
(*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
-       if err != ENOSYS {
-               return err
-       }
+//     err = utimensat(_AT_FDCWD, path,
(*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+//     if err != ENOSYS {
+//             return err
+//     }
        // If the utimensat syscall isn't available (utimensat was