Skip to content

Fix SwipeControl Execute-mode stress crash (0xC0000409) + CI crash-dump capture - #559

Draft
Chris Anderson (codemonkeychris) wants to merge 5 commits into
mainfrom
andersonch/fix-optional-clearvalue-stress-crash
Draft

Chris Anderson (codemonkeychris) wants to merge 5 commits into
mainfrom
andersonch/fix-optional-clearvalue-stress-crash

Conversation

@codemonkeychris

@codemonkeychris Chris Anderson (codemonkeychris) commented Jun 10, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

CI Stress runs (selftest JIT + AOT) intermittently fail-fast with exit 0xC0000409 (notOk=False, no assertion) — ~5–11/1000, landing on seemingly-random spec-050 Optional fixtures. Earlier theories (this PR's first revision, and #539) blamed the Optional ClearValue / AutoSuggestBox popup path; a 1000× JIT re-run disproved that (the crash persisted, including on the already-isolated OptionalThemeInteraction).

Root cause (from a real crash dump)

Added crash-dump capture to ci-stress.yml (full WER dump + on-runner SOS). The dumps show the fault is a WinUI stowed-exception fail-fast:

KERNELBASE!RaiseFailFastException
combase!RoFailFastWithErrorContextInternal2
Microsoft_UI_Xaml!FailFastWithStowedExceptions
Microsoft_UI_Xaml!DirectUI::ErrorHelper::ProcessUnhandledError

0xC0000409 wraps a stored 0xC000027B (STATUS_STOWED_EXCEPTION). The captured managed exception is:

System.ArgumentException: The parameter is incorrect. Execute items should only have one item.
   at Microsoft.UI.Xaml.Controls.SwipeItems.Add(SwipeItem item)
   at SwipeControlDescriptor.CreateSwipeItems(SwipeItemData[] data, SwipeMode mode)   SwipeControlDescriptor.cs:46
   at SwipeControlDescriptor.ApplySwipeItems(...)                                       SwipeControlDescriptor.cs:38
   at ImperativePropEntry.Update → PropEntry.Update → DescriptorHandler.Update

WinUI requires an Execute-mode SwipeItems to contain exactly one item. CreateSwipeItems added every item regardless of mode. The RBC_SwipeControlItemsSwap selftest deterministically builds LeftItemsMode=Execute with two items ([Pin, Mark]), so SwipeItems.Add throws into native WinUI. The throw escapes the imperative reconciler into the XAML dispatcher; ~1/1000 it escalates to a process fail-fast that lands on whichever fixture is currently executing — which is why it looked like a random Optional-fixture crash.

Fix

SwipeControlDescriptor.CreateSwipeItems caps Execute-mode collections to a single item, so invalid authoring can never fail-fast the host.

Also included

CI crash-dump capture for the selftest/AOT stress shards (full WER dumps + a post-failure SOS analysis step that uploads clrthreads / clrstack / pe / dumpheap). This is what made root-causing possible and is retained for future stress investigations.

Validation

  • ✅ Build clean.
  • ✅ --self-test --filter Swipe 40× → 0 crashes; RBC_SwipeControlItemsSwap passes.
  • ✅ SwipeControl unit tests 3/3.
  • ⏳ 1000× JIT CI Stress re-run to confirm the crash rate drops to 0.

CI Stress runs (selftest + AOT) on main fail-fast with exit 0xC0000409 (STATUS_STACK_BUFFER_OVERRUN, notOk=False) concentrated in spec-050 Optional fixtures - 6/10 selftest shards crash inside ControlledOptionalTextInputFamily (which runs AutoSuggestBox).

Root cause (per #539's dump-backed analysis): the Optional .OneWay(dp:) ClearValue path forces a native style/theme re-eval that, combined with AutoSuggestBox popup machinery left in the visual tree, races the next fixture's render under load. #539 hardened only OneWayClearValuePropEntry.Mount and isolated only OptionalThemeInteraction; the other Optional fixtures stayed exposed.

Fixes: (1) OneWayClearValuePropEntry.Update now gates ClearValue on ReadLocalValue(_dp) != UnsetValue, mirroring #539's Mount guard (closes the Update(Of->Unset) crash site). (2) ControlledOptionalTextInputFamily + OptionalEchoStrandRegression fixtures now drain (SetContent(null)+Render) in finally, generalizing #539's per-fixture isolation to the AutoSuggestBox-bearing fixtures.

Validated: host build clean; --self-test --filter Optional EXIT=0 0 failures; PropEntryOptional unit tests 7/7.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codemonkeychris
Chris Anderson (codemonkeychris) marked this pull request as draft June 10, 2026 23:07
@codemonkeychris

Copy link
Copy Markdown
Collaborator Author

Converted to draft: the 1000x JIT stress validation (run 27292566419) still hit 5x 0xC0000409 fail-fast crashes across the Optional fixtures — including \OptionalThemeInteraction\ (shard 23), which already carries #539's full visual-tree isolation and is untouched here. That disproves the ClearValue/popup-contamination theory as the root cause; the crash is an async native fail-fast landing on whichever Optional fixture is running. The \OneWayClearValuePropEntry.Update\ ReadLocalValue gate remains a valid minor hardening, but does not fix the crash. Next step: capture a CI crash dump (DOTNET_DbgEnableMiniDump + artifact upload) to get the real faulting native stack.

Add WER LocalDumps (mini) + CLR createdump (DOTNET_DbgEnableMiniDump) on the selftests and aot-selftests stress jobs, and upload the dumps as an artifact on failure. Captures the faulting native stack for the recurring 0xC0000409 (STATUS_STACK_BUFFER_OVERRUN) fail-fast in the spawned Reactor.AppTests.Host.exe so the crash can be root-caused from a real dump.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codemonkeychris

Copy link
Copy Markdown
Collaborator Author

Dump-backed root cause (run 27371846046)

Added crash-dump capture to ci-stress.yml and re-ran 1000x JIT. 11/14 failing shards were the 0xC0000409 crash; 2 shards produced WER mini-dumps (shard 14 = OptionalThemeInteraction, shard 18 = ControlledOptionalTextInputFamily). Both dumps are identical:

Faulting stack (native):
\
KERNELBASE!RaiseFailFastException
combase!RoFailFastWithErrorContextInternal2
Microsoft_UI_Xaml!FailFastWithStowedExceptions
Microsoft_UI_Xaml!DirectUI::ErrorHelper::ProcessUnhandledError
\\

  • Outer fail-fast exit \

Switch WER LocalDumps to full (DumpType=2) so SOS can read managed stacks/heap, and add a post-failure step that runs dotnet-dump analyze (clrthreads, clrstack -all, pe -nested, dumpheap Exception) on each selftest crash dump and uploads the text. Goal: recover the managed throwing frame behind the 0xC000027B stowed-exception (E_NOINTERFACE/E_POINTER) fail-fast. AOT job keeps native dumps only (NativeAOT has no DAC for SOS).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…fail-fast)

Dump analysis of the CI Stress 0xC0000409 crashes (full WER dump + SOS on the x64 runner) showed the faulting path is a WinUI stowed-exception fail-fast (DirectUI::ErrorHelper::ProcessUnhandledError). The captured managed exception is: System.ArgumentException 'Execute items should only have one item', thrown from Microsoft.UI.Xaml.Controls.SwipeItems.Add inside SwipeControlDescriptor.CreateSwipeItems.

WinUI requires an Execute-mode SwipeItems to contain exactly one SwipeItem; CreateSwipeItems blindly added every item regardless of mode. The RBC_SwipeControlItemsSwap selftest deterministically builds LeftItemsMode=Execute with two items, so the throw escapes the imperative reconciler into the XAML dispatcher; ~1/1000 it escalates to a process fail-fast that lands on whichever fixture is running (explaining the apparent randomness across Optional fixtures).

Fix: CreateSwipeItems caps Execute-mode collections to a single item so invalid authoring can never crash the host. Validated: build clean; Swipe selftests 40x with 0 crashes; SwipeControl unit tests 3/3.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codemonkeychris

Copy link
Copy Markdown
Collaborator Author

ROOT CAUSE FOUND (full dump + SOS)

Switched CI to full WER dumps + an on-runner SOS step (run 27929541307). Captured 2 full dumps and read the managed state (x64 dotnet-dump under ARM64 emulation + forensic string scan of the 1 GB dump).

The fail-fast (\ProcessUnhandledError\ → stowed exception \

Dump analysis proved the stress crash is the SwipeControl Execute-mode bug, not an Optional ClearValue or popup-isolation issue. Revert the OneWayClearValuePropEntry.Update ReadLocalValue gate and the ControlledOptionalTextInputFamily / OptionalEchoStrandRegression fixture drains, which were based on the disproven theory. Keeps the SwipeControl fix and the CI crash-dump capture infrastructure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codemonkeychris Chris Anderson (codemonkeychris) changed the title Fix Optional ClearValue stress crash (0xC0000409) in spec-050 fixtures Fix SwipeControl Execute-mode stress crash (0xC0000409) + CI crash-dump capture Jun 25, 2026

This branch has not been deployed

No deployments
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.

1 participant