runtime: process crash instead of panic on SIGBUS with SetPanicOnDefault(true)
#41,155 opened on Sep 1, 2020
Repository metrics
- Stars
- (133,883 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
What version of Go are you using (go version)?
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
What did you do?
We are using Go for some embedded development (cross compiled to linux arm32). We access various FPGA registers from the Go process. In order to access those registers, we use mmap /dev/mem at the address space of those registers.
When we access registers which are not defined/accessible in the FPGA, the process crash with the error reported below.
We use defer debug.SetPanicOnFault(debug.SetPanicOnFault(true)) in the stack which makes the register read as we expect this to make the runtime panic instead of crash on this kind of memory fault.
What did you expect to see?
A panic where the bad access happened. This way, with a recover call, it would be possible to handle the case where some registers are not available.
What did you see instead?
The process crash, in an unrecoverable way, with the following output:
Unhandled fault: external abort on non-linefetch (0x018) at 0x26b48010
pgd = 5e090000
[26b48010] *pgd=1e234831, *pte=40040703, *ppte=40040e33
runner.sh: SIGBUS: bus error
runner.sh: PC=0x2a8ff0 m=0 sigcode=0
runner.sh: goroutine 43 [running]:
runner.sh: gobv1/pkg/hw/pmem.Access.ReadUint32(...)
runner.sh: C:/projects/ellisys/bv1go/pkg/hw/pmem/memAccess_linux.go:122
runner.sh: gobv1/pkg/hw/pmem.(*Access).ReadUint32(0x925200, 0x10, 0x28e594)
runner.sh: <autogenerated>:1 +0x44 fp=0x8a6acc sp=0x8a6aa4 pc=0x2a8ff0
...
runner.sh: main.(*command).initializeDevice(0x9222c0, 0x922b80)
runner.sh: C:/projects/ellisys/bv1go/cmd/gobv1/main.go:154 +0x94 fp=0x8a6fe4 sp=0x8a6fa0 pc=0x371320
runner.sh: runtime.goexit()
...
runner.sh: goroutine 20 [select]:
runner.sh: io.(*pipe).Read(0x922280, 0x84c000, 0x1000, 0x1000, 0x3b50e8, 0x1136b0, 0x84c000)
runner.sh: C:/Go/src/io/pipe.go:57 +0xac
...
runner.sh: goroutine 42 [runnable]:
...
runner.sh: trap 0x0
runner.sh: error 0x18
runner.sh: oldmask 0x0
runner.sh: r0 0x26b48000
runner.sh: r1 0x3c
runner.sh: r2 0x8a6acc
runner.sh: r3 0x10
runner.sh: r4 0x1
runner.sh: r5 0x1
runner.sh: r6 0xf1
runner.sh: r7 0x26ccc521
runner.sh: r8 0x925200
runner.sh: r9 0x20
runner.sh: r10 0x883500
runner.sh: fp 0x7
runner.sh: ip 0x925203
runner.sh: sp 0x8a6aa4
runner.sh: lr 0x2a8fdc
runner.sh: pc 0x2a8ff0
runner.sh: cpsr 0x80000010
runner.sh: fault 0x0
runner.sh: Program instance execution terminated
Workaround
I build a custom runtime with this commit which makes the call panic as expected.