Fix SwipeControl Execute-mode stress crash (0xC0000409) + CI crash-dump capture - #559
Chris Anderson (codemonkeychris) wants to merge 5 commits into
Conversation
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>
|
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>
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):
|
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>
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>
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 OptionalClearValue/ AutoSuggestBox popup path; a 1000× JIT re-run disproved that (the crash persisted, including on the already-isolatedOptionalThemeInteraction).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:0xC0000409wraps a stored0xC000027B(STATUS_STOWED_EXCEPTION). The captured managed exception is:WinUI requires an
Execute-modeSwipeItemsto contain exactly one item.CreateSwipeItemsadded every item regardless of mode. TheRBC_SwipeControlItemsSwapselftest deterministically buildsLeftItemsMode=Executewith two items ([Pin, Mark]), soSwipeItems.Addthrows 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.CreateSwipeItemscapsExecute-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
--self-test --filter Swipe40× → 0 crashes;RBC_SwipeControlItemsSwappasses.