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)

Most upvoted comments

@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 holding sched.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 for allocm to see the value.