wails/v2/pkg/runtime/signal_linux.go
Lea Anthony 01b661f6a5
feat(v2): add runtime.ResetSignalHandlers() for Linux panic recovery (#4921)
* feat(v2): add runtime.ResetSignalHandlers() for Linux panic recovery

Add a new runtime function that allows users to reset signal handlers
before code that might panic from nil pointer dereferences.

On Linux, WebKit installs signal handlers without the SA_ONSTACK flag,
which prevents Go from properly recovering from panics caused by
SIGSEGV and other signals. This function adds SA_ONSTACK to the
relevant signal handlers (SIGSEGV, SIGBUS, SIGFPE, SIGABRT).

Usage:
```go
go func() {
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Recovered: %v", err)
        }
    }()
    runtime.ResetSignalHandlers()
    // Code that might panic...
}()
```

The function is a no-op on macOS and Windows.

Fixes #3965

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(v2): add panic-recovery-test example

Add an example that demonstrates the Linux signal handler issue (#3965)
and verifies the fix using runtime.ResetSignalHandlers().

The example includes:
- A Greet function that triggers a nil pointer dereference after a delay
- Auto-call from frontend after 5 seconds
- README with reproduction steps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:55:57 +11:00

65 lines
1.4 KiB
Go

//go:build linux
package runtime
/*
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
static void fix_signal(int signum)
{
struct sigaction st;
if (sigaction(signum, NULL, &st) < 0) {
return;
}
st.sa_flags |= SA_ONSTACK;
sigaction(signum, &st, NULL);
}
static void fix_all_signals()
{
#if defined(SIGSEGV)
fix_signal(SIGSEGV);
#endif
#if defined(SIGBUS)
fix_signal(SIGBUS);
#endif
#if defined(SIGFPE)
fix_signal(SIGFPE);
#endif
#if defined(SIGABRT)
fix_signal(SIGABRT);
#endif
}
*/
import "C"
// ResetSignalHandlers resets signal handlers to allow panic recovery.
//
// On Linux, WebKit (used for the webview) may install signal handlers without
// the SA_ONSTACK flag, which prevents Go from properly recovering from panics
// caused by nil pointer dereferences or other memory access violations.
//
// Call this function immediately before code that might panic to ensure
// the signal handlers are properly configured for Go's panic recovery mechanism.
//
// Example usage:
//
// go func() {
// defer func() {
// if err := recover(); err != nil {
// log.Printf("Recovered from panic: %v", err)
// }
// }()
// runtime.ResetSignalHandlers()
// // Code that might panic...
// }()
//
// Note: This function only has an effect on Linux. On other platforms,
// it is a no-op.
func ResetSignalHandlers() {
C.fix_all_signals()
}