golang/go

runtime: process crash instead of panic on SIGBUS with SetPanicOnDefault(true)

Open

#41,155 opened on Sep 1, 2020

View on GitHub
 (12 comments) (0 reactions) (0 assignees)Go (19,008 forks)batch import
NeedsFixcompiler/runtimehelp wanted

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.

Contributor guide