runtime: make divide-by-zero and nil dereference panics recoverable

Modify the Unix signal handler to redirect execution to a Go sigpanic
function instead of printing an error and re-raising the signal.
The C signal handler modifies the ucontext to make the faulting
instruction appear to have called tinygo_sigpanic, which then calls
runtimePanic with the appropriate message.

Supported on all architectures TinyGo targets on Linux and Darwin:
x86_64, i386, aarch64, ARM, and MIPS. Also registers SIGFPE, which
was previously not handled at all.
This commit is contained in:
Jake Bailey
2026-05-10 15:56:07 -07:00
committed by Ron Evans
parent 039f48f3d2
commit 29b4c6723f
12 changed files with 138 additions and 0 deletions
+15
View File
@@ -44,6 +44,9 @@ func main() {
println("\n# recover from nil map and closed channel")
recoverNilMapAndChan()
println("\n# recover from hardware signals")
recoverSignals()
}
func recoverSimple() {
@@ -261,3 +264,15 @@ func recoverNilMapAndChan() {
close(ch)
})
}
// Test recovering from hardware signals (SIGFPE, SIGSEGV).
func recoverSignals() {
recoverMustPanic("divide by zero", func() {
var x int
println(1 / x)
})
recoverMustPanic("nil pointer dereference", func() {
var p *int
println(*p)
})
}
+4
View File
@@ -49,3 +49,7 @@ outer recovered: repanic value
recovered: nil map
recovered: closed chan
recovered: close nil chan
# recover from hardware signals
recovered: divide by zero
recovered: nil pointer dereference