go: runtime: golang.org/cl/46038 causes illegal instruction on FreeBSD/ARM
It is triggered by the os test similarly to this builder log:
signal: illegal instruction (core dumped)
FAIL os 17.079s
Attached a manually built os.test binary and it’s core: os.test_sigill.zip
The corefile itself is not usable under gdb 8.0.1:
[paulzhol@a20 /tmp]$ gdb801 ./os.test os.test-2276.core [7/75]
GNU gdb (GDB) 8.0.1 [GDB v8.0.1 for FreeBSD]
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "armv6-portbld-freebsd11.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./os.test...done.
[New process 100201]
[New process 100297]
[New process 100076]
[New process 100162]
[New process 100191]
[New process 100197]
[New process 100199]
[New process 100202]
[New process 100206]
[New process 100209]
[New process 100210]
warning: Unexpected size of section `.reg/100201' in core file.
warning: wrong size gregset struct in core file
warning: Unexpected size of section `.reg2/100201' in core file.
Core was generated by `/tmp/os.test'.
Program terminated with signal SIGILL, Illegal instruction.
warning: Unexpected size of section `.reg/100201' in core file.
warning: wrong size gregset struct in core file
warning: Unexpected size of section `.reg2/100201' in core file.
#0 <unavailable> in ?? ()
[Current thread is 1 (process 100201)]
Loading Go Runtime support.
(gdb) info threads
PC not available
While running the binary under gdb seems to work:
[paulzhol@a20 /tmp/go/src/os]$ gdb801 /tmp/os.test
GNU gdb (GDB) 8.0.1 [GDB v8.0.1 for FreeBSD]
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "armv6-portbld-freebsd11.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /tmp/os.test...done.
Loading Go Runtime support.
(gdb) run
Starting program: /tmp/os.test
[New LWP 100091 of process 2323]
[New LWP 100234 of process 2323]
[New LWP 100235 of process 2323]
[New LWP 100198 of process 2323]
Thread 3 received signal SIGILL, Illegal instruction.
[Switching to LWP 100234 of process 2323]
runtime.thr_start () at /tmp/go/src/runtime/sys_freebsd_arm.s:65
65 TEXT runtime_thr_start(SB),NOSPLIT,$0
(gdb) list
60 MOVW size+4(FP), R1
61 MOVW $SYS_thr_new, R7
62 SWI $0
63 RET
64
65 TEXT runtime_thr_start(SB),NOSPLIT,$0
66 // set up g
67 MOVW m_g0(R0), g
68 MOVW R0, g_m(g)
69 BL runtime_emptyfunc(SB) // fault if stack check is wrong
(gdb) disassemble
Dump of assembler code for function runtime.thr_start:
=> 0x0006782c <+0>: push {lr} ; (str lr, [sp, #-4]!)
0x00067830 <+4>: ldr r10, [r0]
0x00067834 <+8>: str r0, [r10, #24]
0x00067838 <+12>: bl 0x66cc4 <runtime.emptyfunc>
0x0006783c <+16>: bl 0x3e8cc <runtime.mstart>
0x00067840 <+20>: mov r8, #2, 0
0x00067844 <+24>: str r8, [r8]
0x00067848 <+28>: pop {pc} ; (ldr pc, [sp], #4)
End of assembler dump.
(gdb) info threads
Id Target Id Frame
1 LWP 100233 of process 2323 runtime.sys_umtx_op () at /tmp/go/src/runtime/sys_freebsd_arm.s:53
2 LWP 100091 of process 2323 runtime.usleep () at /tmp/go/src/runtime/sys_freebsd_arm.s:319
* 3 LWP 100234 of process 2323 runtime.thr_start () at /tmp/go/src/runtime/sys_freebsd_arm.s:65
4 LWP 100235 of process 2323 runtime.sys_umtx_op () at /tmp/go/src/runtime/sys_freebsd_arm.s:53
5 LWP 100198 of process 2323 runtime.thr_start () at /tmp/go/src/runtime/sys_freebsd_arm.s:65
(gdb) info goroutines
1 waiting runtime.gopark
2 waiting runtime.gopark
17 waiting runtime.gopark
3 waiting runtime.gopark
* 4 syscall runtime.systemstack_switch
60 runnable runtime.gopark
62 runnable os_test.TestProgWideChdir.func1
63 runnable os_test.TestProgWideChdir.func1
64 runnable runtime.gopark
67 runnable os_test.TestProgWideChdir.func1
68 runnable os_test.TestProgWideChdir.func1
69 runnable os_test.TestProgWideChdir.func1
70 runnable os_test.TestProgWideChdir.func1
(gdb) goroutine 4 bt
#0 runtime.systemstack_switch () at /tmp/go/src/runtime/asm_arm.s:210
#1 0x00038648 in runtime.futexsleep (addr=0x212048 <runtime.sig>, val=0, ns=-1) at /tmp/go/src/runtime/os_freebsd.go:148
#2 0x0001e78c in runtime.notetsleep_internal (n=0x212048 <runtime.sig>, ns=-1, ~r2=false) at /tmp/go/src/runtime/lock_futex.go:174
#3 0x0001ea34 in runtime.notetsleepg (n=0x212048 <runtime.sig>, ns=-1, ~r2=true) at /tmp/go/src/runtime/lock_futex.go:228
#4 0x0005112c in os/signal.signal_recv (~r0=0) at /tmp/go/src/runtime/sigqueue.go:131
#5 0x000fefa4 in os/signal.loop () at /tmp/go/src/os/signal/signal_unix.go:22
#6 0x00066f00 in runtime.goexit () at /tmp/go/src/runtime/asm_arm.s:929
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 16 (14 by maintainers)
@aclements would know better but I don’t think any memory barriers are required here because the only case that needs to read this field is holding
sched.lock
, and that code only needs to see a linked list that was created while also using holdingsched.lock
, and as such all memory barriers will have been executed anyhow by the lock code. That is, this is not a case of so-called lock-free programming, this is just a case where we need to definitely set a single field to 0. Really an ordinary non-atomic store ought to work fine too, since there is nothing setting the field to non-0, it just might take longer forallocm
to see the value.