-
Notifications
You must be signed in to change notification settings - Fork 804
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 from C++/CX to C++/WinRT (WinUI2, MUXC 2.8.7), but happens on WinUI3 too. Minimal repro 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
- no crash if C++/CX was used to implement SplitButtonDerived class - it is C++/WinRT related regression
- no crash if MUXC::SplitButton is used directly, without deriving from it
- 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
- there is crash if MUXC::ToggleSplitButton is used as base for the derived control
- there is crash if OS WUXC::[Toggle]SplitButton is used as base for the derived control
- there is crash if WinUI3::[Toggle]SplitButton is used as base for the derived control
- 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
- Open minimal repro SplitButtonDerived_CppWinRTCrashOnDestruction_WinUI3.zip, run SplitButtonDerived_CppWinRT or SplitButtonDerived_WinUI3 project, see "C++/WinRT SplitButtonDerived" control
- Click "Click Me" button to navigate away from MainPage
- 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