Skip to content

fix(v2/linux): fix crash on panic in JS-bound Go methods#4855

Merged
leaanthony merged 3 commits into
masterfrom
fix/v2-3965-signal-handler-crash
Jan 25, 2026
Merged

fix(v2/linux): fix crash on panic in JS-bound Go methods#4855
leaanthony merged 3 commits into
masterfrom
fix/v2-3965-signal-handler-crash

Conversation

@leaanthony

@leaanthony leaanthony commented Jan 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Fix Linux crash when Go code panics in JS-bound methods (e.g., nil pointer dereference)
  • Root cause: WebKit2GTK installs signal handlers without SA_ONSTACK after gtk_main() starts, overriding our fix
  • Solution: Defer signal handler installation via g_idle_add() to run after GTK main loop starts

Problem

When Go code called from JavaScript panics (e.g., nil pointer dereference), the app crashes with:

fatal error: non-Go code set up signal handler without SA_ONSTACK flag

This happens because:

  1. install_signal_handlers() was called before gtk_main()
  2. WebKit2GTK installs its own signal handlers after GTK main loop starts
  3. WebKit's handlers don't have SA_ONSTACK, causing Go runtime to crash on signals

Solution

Use g_idle_add() to schedule signal handler installation after GTK main loop starts, ensuring we fix handlers AFTER WebKit has installed its own.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Compilation verified on Linux with webkit2_41 build tag

Fixes #3965

Summary by CodeRabbit

  • Bug Fixes
    • Improved application initialization stability on Linux by optimizing system signal handling during startup.

✏️ Tip: You can customize this high-level summary in your review settings.

WebKit2GTK installs signal handlers after gtk_main() starts, overriding
our SA_ONSTACK fix. This causes Go panics (e.g., nil pointer dereference)
in JS-bound methods to crash with 'non-Go code set up signal handler
without SA_ONSTACK flag'.

Fix by deferring signal handler installation via g_idle_add() to run
after GTK main loop starts, ensuring we fix handlers AFTER WebKit
has installed its own.

Fixes #3965
@coderabbitai

coderabbitai Bot commented Jan 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@leaanthony has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Defers GTK signal handler installation until after GTK initialization completes by scheduling handler setup via GTK idle callbacks. This prevents signal handler race conditions on Linux where handlers were installed before GTK was fully initialized.

Changes

Cohort / File(s) Summary
Linux Signal Handler Initialization
v2/internal/frontend/desktop/linux/frontend.go
Adds fix_signal_handlers_after_gtk_init() function that uses GTK idle callbacks (g_idle_add) to schedule signal handler installation after GTK initialization. Go code now calls C.fix_signal_handlers_after_gtk_init() instead of direct C.install_signal_handlers() to prevent initialization race conditions.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

Bug, Linux, go, size:M

Suggested reviewers

  • makew0rld

Poem

🐰 A signal once wild, now tamed with care,
Idle callbacks schedule handlers with flair,
GTK waits, then whispers its call,
No more crashes when handlers sprawl!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: addressing a crash on panic in JS-bound Go methods on Linux.
Description check ✅ Passed The description includes summary, problem analysis, solution, type of change, testing evidence, and issue reference as required by the template.
Linked Issues check ✅ Passed The code changes directly address issue #3965 by deferring signal handler installation via g_idle_add() to execute after GTK starts, preventing WebKit from overriding SA_ONSTACK flags.
Out of Scope Changes check ✅ Passed All changes are narrowly scoped to fixing the signal handler timing issue in Linux desktop frontend, with no unrelated modifications.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
v2/internal/frontend/desktop/linux/frontend.go (1)

76-84: LGTM! Consider adding explanatory comments.

The implementation correctly uses g_idle_add to defer signal handler installation until after the GTK main loop starts, which ensures WebKit2GTK has installed its handlers first. The callback properly returns G_SOURCE_REMOVE to execute only once.

Consider adding a brief comment explaining the WebKit timing issue to help future maintainers understand why this deferral is necessary. For example:

// WebKit2GTK installs signal handlers without SA_ONSTACK after gtk_main() starts,
// overriding the Go runtime's handlers. We use g_idle_add to fix them after WebKit
// initialization completes. See: https://github.com/wailsapp/wails/issues/3965
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6630fa5 and 8e385f4.

📒 Files selected for processing (1)
  • v2/internal/frontend/desktop/linux/frontend.go
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Sammy-T
Repo: wailsapp/wails PR: 4570
File: v2/internal/frontend/desktop/linux/window_webkit6.go:97-108
Timestamp: 2025-10-17T23:16:11.570Z
Learning: For webkit_6/GTK4 builds in v2/internal/frontend/desktop/linux/window_webkit6.go, GTK widget creation should not be wrapped in invokeOnMainThread. The activation mechanism (activateWg + onActivate export) already handles thread safety, and additional wrapping would cause issues.
Learnt from: APshenkin
Repo: wailsapp/wails PR: 4480
File: v2/internal/frontend/desktop/darwin/message.h:17-19
Timestamp: 2025-08-08T09:13:16.916Z
Learning: In Wails v2 bindings origin verification, processBindingMessage intentionally has different signatures across platforms: Darwin includes an isMainFrame bool (WKWebKit provides it), Linux uses two params (message, source) as WebKitGTK doesn’t expose main-frame info there, and Windows handles origin checks in Go via WebView2 sender/args without a C bridge. This divergence is acceptable/expected per maintainer (APshenkin).
📚 Learning: 2025-10-17T23:16:11.570Z
Learnt from: Sammy-T
Repo: wailsapp/wails PR: 4570
File: v2/internal/frontend/desktop/linux/window_webkit6.go:97-108
Timestamp: 2025-10-17T23:16:11.570Z
Learning: For webkit_6/GTK4 builds in v2/internal/frontend/desktop/linux/window_webkit6.go, GTK widget creation should not be wrapped in invokeOnMainThread. The activation mechanism (activateWg + onActivate export) already handles thread safety, and additional wrapping would cause issues.

Applied to files:

  • v2/internal/frontend/desktop/linux/frontend.go
📚 Learning: 2025-12-29T08:02:06.122Z
Learnt from: popaprozac
Repo: wailsapp/wails PR: 4839
File: docs/src/content/docs/reference/window.mdx:616-620
Timestamp: 2025-12-29T08:02:06.122Z
Learning: In Wails v3, the correct API for creating windows is `app.Window.New()` and `app.Window.NewWithOptions(...)`, not `app.NewWebviewWindow()` or `app.NewWebviewWindowWithOptions(...)`. The Application struct exposes a Window field of type *WindowManager that provides these methods.

Applied to files:

  • v2/internal/frontend/desktop/linux/frontend.go
📚 Learning: 2026-01-04T08:01:00.038Z
Learnt from: symball
Repo: wailsapp/wails PR: 4853
File: v2/internal/system/system.go:128-152
Timestamp: 2026-01-04T08:01:00.038Z
Learning: In v2/internal/system/system.go, shared functions like checkLibrary are defined without build tags but are only invoked from platform-specific files (system_linux.go, system_windows.go, system_darwin.go) that have build constraints. Reviewers should ensure there are no runtime OS checks in system.go and that platform-specific behavior is controlled via build tags. If runtime switches exist, remove them in favor of compile-time platform constraints to reduce overhead and improve correctness.

Applied to files:

  • v2/internal/frontend/desktop/linux/frontend.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: semgrep/ci
  • GitHub Check: Run Go Tests (windows-latest, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-24.04, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-22.04, 1.23)
  • GitHub Check: Run Go Tests (macos-latest, 1.23)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
v2/internal/frontend/desktop/linux/frontend.go (1)

217-217: The signal handler deferral via g_idle_add() is correctly timed and fixes the intended issue.

The implementation is sound. By calling fix_signal_handlers_after_gtk_init() before gtk_main(), the idle callback is registered to execute once the main loop is active. This ensures signal handlers are fixed after WebKit2GTK installs its own handlers during gtk_main() startup, allowing the SA_ONSTACK flag to be properly applied to prevent panics in Go-bound methods when signals occur.

The change has been tested and verified to work correctly on webkit2_41.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jan 4, 2026

Copy link
Copy Markdown

Deploying wails with  Cloudflare Pages  Cloudflare Pages

Latest commit: f451efd
Status:⚡️  Build in progress...

View logs

@leaanthony leaanthony merged commit 7ee2b2d into master Jan 25, 2026
14 of 16 checks passed
@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label Jan 25, 2026
@leaanthony leaanthony deleted the fix/v2-3965-signal-handler-crash branch January 25, 2026 01:39
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation Linux v2-only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

app crash if "invalid memory address or nil pointer dereference"

1 participant