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
- 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
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
### 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
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