microsoft / microsoft/microsoft-ui-xaml

[SplitButton, WinUI3, MUX 2.8.7, WUX] Crash on destruction of control derived from SplitButton using C++/WinRT projection, minimal repro attached

Open
#10,502 2 comments 0 reactions 0 assignees View on GitHub
area-SplitButton bug Crash
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

Crash occurs when control derived from MUXC SplitButton using C++/WinRT projection is placed on some Page, and then this Page is destructed during navigation away to other Page.

Crash was found during porting [Live Home 3D](https://www.livehome3d.com/) from C++/CX to C++/WinRT (WinUI2, MUXC 2.8.7), but happens on WinUI3 too. Minimal repro [SplitButtonDerived_CppWinRTCrashOnDestruction_WinUI3.zip](https://github.com/user-attachments/files/19683826/SplitButtonDerived_CppWinRTCrashOnDestruction_WinUI3.zip) has three almost identical WinUI3, WinUI2 C++/WinRT and WinUI2 C++/CX projects with simplest possible SplitButtonDerived, crash happens only in WinUI3 and WinUI2 C++/WinRT, but not in WinUI2 C++/CX

1) no crash if C++/CX was used to implement SplitButtonDerived class - it is C++/WinRT related regression
2) no crash if MUXC::SplitButton is used directly, without deriving from it
3) no crash if MUXC::DropDownButton is used instead of MUXC::SplitButton as base for the derived control - **crash is strongly connected to MUXC::SplitButton implementation**
4) there is crash if MUXC::ToggleSplitButton is used as base for the derived control
5) there is crash if OS WUXC::[Toggle]SplitButton is used as base for the derived control
6) there is crash if WinUI3::[Toggle]SplitButton is used as base for the derived control
7) SplitButtonDerived can be simplest possible, without extra code or custom style, as in minimal repro - crash will happen

Following callstack is from WinUI2 C++/WinRT project, as I cannot obtain symbols for WinUI3 1.7 Microsoft.UI.Xaml.dll
Image

From preliminar investigation, it seems that core CContentControl tried to release his DXamlPeer == DirectUI::ContentControl, that is part of COM composite object DirectUI::ContentControl + MUXC::SplitButton + CppWinRT::SplitButtonDerived. But something with reference counting went wrong, and outer parts of the composite are destructed (breakpoints placed on SplitButtonDerived::.dtor and SplitButton::.dtor are triggered), but inner part remained alive (DependencyObject::OnFinalRelease() is not called, breakpoint on it is not triggered, and therefore DXamlPeer was not disconnected from core object), and then code in CContentControl used partially destructed COM composite object.

Following breakpoint in DirectUI::DependencyObject::OnFinalRelease() is reached for C++/CX SplitButtonDerived, but is not reached for C++/WinRT SplitButtonDerived, that clearly shows that inner part of DirectUI::ContentControl + MUXC::SplitButton + CppWinRT::SplitButtonDerived composite is not destructed
Image

### Steps to reproduce the bug

1. Open minimal repro [SplitButtonDerived_CppWinRTCrashOnDestruction_WinUI3.zip](https://github.com/user-attachments/files/19683826/SplitButtonDerived_CppWinRTCrashOnDestruction_WinUI3.zip), run SplitButtonDerived_CppWinRT or SplitButtonDerived_WinUI3 project, see "C++/WinRT SplitButtonDerived" control
2. Click "Click Me" button to navigate away from MainPage
3. Crash on destruction

### Expected behavior

No crash

### NuGet package version

WinUI 3 - WindowsAppSDK 1.7
WinUI 2 - Microsoft.UI.Xaml 2.8.7
OS WUXC::SplitButton affected too

### Windows version

Windows 11 (24H2): Build 26100

Contributor guide

Open the contributing guide

Research direction

Start with the attached SplitButtonDerived_CppWinRTCrashOnDestruction_WinUI3.zip repro and run the SplitButtonDerived_CppWinRT or SplitButton_WinUI3 project. Navigate away from MainPage with the Click Me button and compare the C++/WinRT, WinUI 3, and C++/CX cases using the reported callstack and breakpoints. Done means the derived SplitButton no longer crashes during destruction.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.