Skip to content

fix(v3/windows): keep uxtheme.dll loaded after resolving ordinals - #6358

Merged
leaanthony merged 1 commit into
wailsapp:masterfrom
DangTAnh:pr/6356-uxtheme-handle
Oct 26, 2026
Merged

leaanthony merged 1 commit into
wailsapp:masterfrom
DangTAnh:pr/6356-uxtheme-handle

Conversation

@DangTAnh

@DangTAnh DangTAnh commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

pkg/w32's init loads uxtheme.dll, resolves ordinals 132/133/135/136/104 and stores the raw function addresses in package-level variables, then calls windows.FreeLibrary(localUXTheme). applyDarkMode calls AllowDarkModeForWindow through one of those pointers later, when the first window opens. If nothing else has mapped uxtheme in the meantime, the call jumps into unmapped memory and crashes the app (access violation in application.(*windowsWebviewWindow).applyDarkMode).

Keep the module loaded for the process lifetime because those pointers remain in use. This is the minimal fix; ordinal loading and the LazyDLL path are unchanged.

Fixes #6356

Type of change

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

How Has This Been Tested?

  • Windows
cd v3 && go test ./pkg/w32 -count=1              # ok
cd v3 && go build ./pkg/w32 ./pkg/application    # exit 0

A throwaway probe outside the repo confirmed uxtheme.dll is resident after pkg/w32 init (GetModuleHandleEx returns a handle; it is not loaded in a process that does not import pkg/w32).

Limitation: on this Windows build (11, 26300) the module stays loaded even with the old free sequence, apparently because RefreshImmersiveColorPolicyState pins it, so the original crash was not reproduced locally. The fix removes the unload that creates the stale-pointer precondition described in the issue. No automated test was added because loader state is OS/build-dependent and would pass pre-fix on this machine.

A v3/UNRELEASED_CHANGELOG.md entry was added under Fixed.

Test Configuration

# System
Platform     | windows
Version      | 2009 (Build: 26300)
Branding     | Windows 11
Architecture | amd64
WebView2     | 155.0.4283.62

# Build Environment
Wails CLI    | v3.0.0-dev
Go Version   | go1.26.9
CGO_ENABLED  | 1

Checklist:

  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • Bug Fixes
    • Fixed a Windows crash that could occur when applying dark mode.

…app#6356)

pkg/w32's init resolved uxtheme ordinal functions into package-level
variables and then freed the module. applyDarkMode calls those pointers
later, so the call can jump into unmapped memory and crash the first
window on some Windows builds. Keep the module loaded for the process
lifetime while those pointers are in use.
@github-actions github-actions Bot added Bug Something isn't working v3 labels Oct 26, 2026
@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 473da0a and f18586b.

Files selected for processing: 2
  • v3/UNRELEASED_CHANGELOG.md
  • v3/pkg/w32/theme.go

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Walkthrough

The Windows theme package no longer frees uxtheme.dll after initialization. The changelog records that the module stays loaded while its ordinal procedure pointers may be used.

Changes

Windows theme module lifetime

Layer / File(s) Summary
Retain the theme module
v3/pkg/w32/theme.go, v3/UNRELEASED_CHANGELOG.md
Initialization no longer calls windows.FreeLibrary for uxtheme.dll. The changelog records that the module remains loaded while its procedure pointers may be used.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested labels: Bug, Documentation, v3

Suggested reviewers: leaanthony

Merge Risk: Minimal · up to f1858

The change prevents the reported Windows dark-mode crash by retaining the theme module for the required lifetime.

Pre-merge checks: Passed 4 · Failed 1

Failed 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%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the Windows fix: keeping uxtheme.dll loaded after resolving ordinal functions.
Description check Passed The description explains the crash cause, fix, linked issue, testing, test environment, limitation, and changelog update. It also marks the bug-fix type and relevant checklist items.
Linked Issues check Passed The change satisfies #6356. In v3/pkg/w32/theme.go, the PR removes windows.FreeLibrary(localUXTheme) after resolving the uxtheme ordinal pointers. The pointers therefore remain valid for later `ap…
Out of Scope Changes check Passed The reviewed changes are limited to the uxtheme lifetime fix in v3/pkg/w32/theme.go and its related v3/UNRELEASED_CHANGELOG.md entry. The ordinal loading and LazyDLL path remain unchanged. No un…
Full details: Linked Issues check

Explanation

The change satisfies #6356. In v3/pkg/w32/theme.go, the PR removes windows.FreeLibrary(localUXTheme) after resolving the uxtheme ordinal pointers. The pointers therefore remain valid for later applyDarkMode calls. The PR also reports successful Windows package tests and builds. The changelog records the fix.

Full details: Out of Scope Changes check

Explanation

The reviewed changes are limited to the uxtheme lifetime fix in v3/pkg/w32/theme.go and its related v3/UNRELEASED_CHANGELOG.md entry. The ordinal loading and LazyDLL path remain unchanged. No unrelated change is demonstrated.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 golangci-lint (2.14.0)

level=error msg="[linters_context] typechecking error: build constraints exclude all Go files in /v3/pkg/w32"

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

A rabbit checks the theme DLL,
Its function pointers stay put still.
The module lingers through the day,
While dark mode finds its safe old way.
The changelog notes the change in ink.
This bunny hops, then stops to think.

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

@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label Oct 26, 2026

@leaanthony leaanthony left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @DangTAnh ya legend!

@leaanthony
leaanthony merged commit f9dcfef into wailsapp:master Oct 26, 2026
59 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working Documentation Improvements or additions to documentation v3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v3] Windows: crash in applyDarkMode after pkg/w32's init frees uxtheme.dll

2 participants