Skip to content

[v3] (*Chromium).Focus race on production startup — #4835 fix has TOCTOU window #5446

@haohow123

Description

@haohow123

Description

Hitting the same crash signature as #4835 in alpha.90 production build (not dev mode). The fix from #4835 (commit 464659b — `GetController() != nil` guards in `webview_window_windows.go`) is present in our build, but the check and the subsequent `Focus()` call are non-atomic: in our crash trace the controller has been torn down between the guard at line 1023 and the call at line 1028.

Stack trace (production launcher.log, ~4 s after `App.Run`)

```
[WebView2 Error] The parameter is incorrect.

1: github.com/wailsapp/wails/webview2/pkg/edge.(*Chromium).errorCallback
github.com/wailsapp/wails/webview2@v1.0.24/pkg/edge/chromium.go:151
2: github.com/wailsapp/wails/webview2/pkg/edge.(*Chromium).Focus
github.com/wailsapp/wails/webview2@v1.0.24/pkg/edge/chromium.go:575
3: github.com/wailsapp/wails/v3/pkg/application.(*windowsWebviewWindow).focus
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/webview_window_windows.go:1028
4: github.com/wailsapp/wails/v3/pkg/application.(*windowsWebviewWindow).WndProc
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/webview_window_windows.go:1546
5: github.com/wailsapp/wails/v3/pkg/application.(*windowsApp).wndProc
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/application_windows.go:303
```

(Identical shape to the trace in #4835, just from a production binary instead of `wails3 dev` hot-reload.)

Race

`v3/pkg/application/webview_window_windows.go` alpha.90:

```go
1009: func (w *windowsWebviewWindow) focus() {
...
1023: if w.chromium.GetController() == nil {
1024: return
1025: }
// ── another goroutine can tear the controller down here ──
1028: w.chromium.Focus() // crashes when controller is now nil/destroyed
}
```

The other three `chromium.Focus()` call sites in the same file (lines 884–885, 896–897, 945–946) have the same shape — `GetController() != nil` then call — so the same TOCTOU window exists for each.

Trigger

Not deterministic — surfaces ~1 in 10 cold launches of a Wails v3 launcher on Windows 11, ~4 s after `App.Run`. The window message landing in `WndProc` while WebView2's controller is still initialising seems to be the trigger. dev hot-reload (the #4835 reproducer) is not involved.

Suggested fix direction

  1. Snapshot the controller pointer under `w.chromium`'s lock inside `focus()` (and the other three sites) and call `Focus()` only on the snapshot, OR
  2. Defer focus messages until the controller has finished initialising (e.g. queue them and drain after `WebView2 Environment created successfully` fires).

Either keeps the fix local to the affected call sites without changing the broader controller lifecycle.

Versions

  • Wails v3: `v3.0.0-alpha.90`
  • Windows 10/11
  • WebView2 runtime: whatever Windows ships
  • Build: production (`-tags production -H windowsgui`), tag-triggered release workflow

Cross-ref: #4835 (closed, partial fix landed in 464659b — covers nil controller but not the race).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions