Skip to content

fix(linux): stop forcing SA_ONSTACK on SIGUSR1 to prevent WebKit freeze#5530

Merged
leaanthony merged 3 commits into
masterfrom
claude/wails-issue-5527-Tjtrf
Jun 3, 2026
Merged

fix(linux): stop forcing SA_ONSTACK on SIGUSR1 to prevent WebKit freeze#5530
leaanthony merged 3 commits into
masterfrom
claude/wails-issue-5527-Tjtrf

Conversation

@leaanthony

@leaanthony leaanthony commented Jun 2, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #5527 — a regression introduced in alpha.97 where the WebKit UI freezes on Linux while idle (most visibly with the inspector open). Only the UI hangs; the Go backend keeps running.

Root cause

The freeze traces to PR #5507 (6329e9d), the only Linux/WebKit signal-handling change between alpha.96 and alpha.97. That commit added fix_signal(SIGUSR1) to install_signal_handlers().

  • SIGUSR1 (signal 10 on Linux) is the signal WebKit's JavaScriptCore uses to suspend/resume threads for conservative GC stack scanning.
  • fix_signal() ORs SA_ONSTACK into whatever handler is currently registered. Once JSC installs its own SIGUSR1 handler, Go no longer handles SIGUSR1 at all, so forcing SA_ONSTACK only corrupts JSC's handler — making it run on Go's alternate signal stack instead of the thread's normal stack.
  • This breaks JSC's GC thread synchronisation, deadlocking WebKit during idle garbage collection (tab away → GC runs → freeze). An open inspector keeps JS/GC active, which is why it reproduces so reliably there.

The original commit even noted the Overriding existing handler for signal 10 message — that is JSC taking ownership of SIGUSR1, which is exactly the point at which adding SA_ONSTACK becomes harmful rather than helpful.

Fix

Remove fix_signal(SIGUSR1) from install_signal_handlers() in all three locations:

  • v3/pkg/application/linux_cgo.c (GTK4)
  • v3/pkg/application/linux_cgo_gtk3.go (GTK3)
  • v2/internal/frontend/desktop/linux/frontend.go

Each is replaced with a comment explaining why SIGUSR1 must not be touched. The genuine #5506 fix for SIGSEGV/SIGBUS (which Go does require SA_ONSTACK for, for JIT crash recovery) is fully preserved.

Testing

  • gofmt clean on the modified Go file.
  • A full CGO build was not possible in the dev environment (GTK4 dev headers not installed), but the change is a pure removal of two preprocessor lines plus comments.
  • Runtime validation recommended with the issue's repro: set OpenInspectorOnStartup: true, wails3 dev, tab away for a few minutes.

Fixes #5527

https://claude.ai/code/session_01AtT1CjDNRArXv1eddXte2a


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Resolved UI freeze on Linux when WebKit is idle with the inspector open.

WebKit's JavaScriptCore uses SIGUSR1 to suspend/resume threads for
conservative GC stack scanning. The signal-handler fix added in
alpha.97 (#5507) re-applied SA_ONSTACK to every signal it touched,
including SIGUSR1. Once JSC installs its own SIGUSR1 handler it owns the
signal (Go no longer handles it), so forcing SA_ONSTACK makes that
handler run on Go's alternate signal stack, breaking GC thread
synchronisation. This froze the WebKit UI during idle garbage
collection (most visibly with the inspector open) while the Go backend
kept running.

Remove fix_signal(SIGUSR1) from install_signal_handlers in v3 (GTK4 +
GTK3) and v2. The genuine #5506 fix for SIGSEGV/SIGBUS (which Go needs
SA_ONSTACK for) is unaffected.

Fixes #5527

https://claude.ai/code/session_01AtT1CjDNRArXv1eddXte2a
Copilot AI review requested due to automatic review settings June 2, 2026 20:08
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 35e125f8-fb4a-4b1b-9f48-747211fe24e1

📥 Commits

Reviewing files that changed from the base of the PR and between aa31c67 and bbe1ea5.

📒 Files selected for processing (4)
  • v2/internal/frontend/desktop/linux/frontend.go
  • v3/UNRELEASED_CHANGELOG.md
  • v3/pkg/application/linux_cgo.c
  • v3/pkg/application/linux_cgo_gtk3.go

Walkthrough

This PR fixes a UI freeze on Linux with the inspector open by removing the SA_ONSTACK flag from SIGUSR1 signal handling across v2 and v3 codebases. WebKit's JavaScriptCore uses SIGUSR1 for garbage collection stack scanning and thread synchronization; forcing SA_ONSTACK conflicts with that usage and causes WebKit to freeze during idle collection.

Changes

SIGUSR1 signal handling fix for WebKit idle freeze

Layer / File(s) Summary
v3 C signal handler fix
v3/pkg/application/linux_cgo.c, v3/pkg/application/linux_cgo_gtk3.go
install_signal_handlers in v3 no longer applies fix_signal(SIGUSR1) or SA_ONSTACK to SIGUSR1. Comments explain that JavaScriptCore manages SIGUSR1 for GC stack scanning and thread suspend/resume, and SA_ONSTACK would break GC thread synchronization.
v2 frontend signal handler fix
v2/internal/frontend/desktop/linux/frontend.go
Linux frontend cgo signal setup removes fix_signal(SIGUSR1) and adds comments documenting that SA_ONSTACK must not be applied to SIGUSR1 due to WebKit/JavaScriptCore GC usage and idle freeze risk.
Fix documentation
v3/UNRELEASED_CHANGELOG.md
Changelog entry added under Fixed section describing the Linux WebKit UI freeze mitigation via SIGUSR1 signal handler change, referencing issue #5527.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • wailsapp/wails#5507: Modifies SIGUSR1 signal handling in the same code paths but applies the SA_ONSTACK fix periodically to survive JSC lazy initialization—inverse approach to this PR's removal.
  • wailsapp/wails#4856: Adjusts install_signal_handlers logic to control when SA_ONSTACK is applied to avoid WebKit override conflicts.
  • wailsapp/wails#4855: Defers signal handler installation on Linux/GTK to prevent WebKit from overriding Go runtime signal configuration.

Suggested labels

Linux, v2-only

Suggested reviewers

  • makew0rld

Poem

🐰 A signal sleeps on silent stacks,
WebKit runs its GC tracks,
No forcing hands upon SIGUSR1—
Now JavaScriptCore's work is done.
The inspector opens, frost melts away,
The frozen UI lives to say: hooray!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: stopping the forcing of SA_ONSTACK on SIGUSR1 to prevent WebKit freeze, which directly addresses the core issue.
Description check ✅ Passed The PR description comprehensively covers the root cause, fix, testing, and includes a clear 'Fixes #5527' reference, though the checklist items are not explicitly marked off.
Linked Issues check ✅ Passed The PR fully addresses the requirements from issue #5527 by removing the problematic fix_signal(SIGUSR1) calls from all three signal-handler locations and preserving the intended SIGSEGV/SIGBUS fix.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the WebKit freeze issue by removing SIGUSR1 signal-handler modifications; no unrelated changes are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/wails-issue-5527-Tjtrf

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"

🔧 Infer (1.2.0)
v3/pkg/application/linux_cgo.c

In file included from v3/pkg/application/linux_cgo.c:3:
v3/pkg/application/linux_cgo.h:6:10: fatal error: 'gtk/gtk.h' file not found
6 | #include <gtk/gtk.h>
| ^~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/bbe1ea58c5877177eb4c09b0573714f2f4083515-404c81ed9c8d9c90/tmp/clang_command_.tmp.ca7cd3.txt
++Contents of '/tmp/coderabbit-infer/bbe1ea58c5877177eb4c09b0573714f2f4083515-404c81ed9c8d9c90/tmp/clang_command_.tmp.ca7cd3.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown-lin

... [truncated 759 characters] ...

inux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/404c81ed9c8d9c90/file.o" "-x" "c"
"v3/pkg/application/linux_cgo.c" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"


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.

Copilot AI 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.

Pull request overview

This PR addresses a Linux-specific WebKit freeze regression introduced in v3 alpha.97 by stopping Wails from forcing SA_ONSTACK onto SIGUSR1, which JavaScriptCore uses for GC thread coordination.

Changes:

  • Remove fix_signal(SIGUSR1) from Linux/WebKit signal handler installation in v2 + v3 (GTK3/GTK4).
  • Add inline comments documenting why SIGUSR1 must not be modified.
  • Add a v3 changelog entry describing the fix and linking to #5527.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
v3/UNRELEASED_CHANGELOG.md Documents the Linux WebKit idle/inspector freeze fix for the next v3 alpha release.
v3/pkg/application/linux_cgo.c Stops applying SA_ONSTACK to SIGUSR1 in the GTK4 signal-handler fix path; adds rationale comment.
v3/pkg/application/linux_cgo_gtk3.go Stops applying SA_ONSTACK to SIGUSR1 in the GTK3 signal-handler fix path; adds rationale comment.
v2/internal/frontend/desktop/linux/frontend.go Stops applying SA_ONSTACK to SIGUSR1 in the v2 Linux frontend signal-handler fix path; adds rationale comment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@leaanthony leaanthony merged commit ef782b7 into master Jun 3, 2026
21 checks passed
@leaanthony leaanthony deleted the claude/wails-issue-5527-Tjtrf branch June 3, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v3] Freezes with open inspector on linux.

3 participants