yuyoyuppe
Topic Author
Posts: 7
Joined: 06 Apr 2021, 12:46

Weird nullptr crash with *Items

27 Aug 2023, 20:45

Unfortunately, this bug manifests only in our app and disappears with any toy examples, so I'm giving as much context as could be useful, because it seems like an interplay between multiple things. Please also note that we're not using NoesisApp package.

We've implemented a set of UserControls which simulate a switch/case statement in XAML and use this pattern extensively:
<local:Switch Source="{Binding ActiveScreen}">
    <local:Case Value="MainMenu">
        <local:Partial Path="../Screens/MainMenu.xaml" DataContext="{Binding MainMenuVM}" />
    </local:Case>

    <local:Case Value="Settings">
        <local:Partial Path="../Screens/Settings.xaml" DataContext="{Binding SettingsVM}" />
    </local:Case>
    
    <!-- etc. -->
</local:Switch>
Thus, we're able to switch between the screens from UI. Switch just calls SetVisibility on Cases appropriately. Some of the screens contain Noesis::Menus and Noesis::ComboBoxs, and they in turn either declare inline or bind to Noesis::ObservableCollections of Noesis::MenuItems and Noesis::ComboBoxItems. Here's a typical example of how we use Menu with MenuItems:
<Menu>
    <MenuItem Header="File">
        <MenuItem Header="Open" Command="{Binding OpenCommand}" />
        <MenuItem Header="Exit" Command="{Binding ExitCommand}" />
    </MenuItem>
</Menu>
So, nothing special. However, we do incorrectly (from the MVVM p.o.v.) create and bind ComboBoxItems as part of some VMs for ComboBoxs ItemsSource. Using those controls and going back and forth between screens cause an error like this:
[DependencyObject.cpp:1375] Value cannot be assigned to the property 'ComboBoxItem..ContainerItem' (property has type 'BaseComponent', value has type 'BaseObject')
and an immediate crash afterwards with a callstack like that:
// Noesis.dll v3.2.1, x86_64 on Windows, loaded at base address: 0x00007FFCDF9D0000
// 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF or somewhere around nullptr
00007ffcdfb4b076()	Unknown
Noesis::DependencyObject::InternalSetValue() + 938 bytes	Unknown
Noesis::FrameworkElement::SetUseLayoutRounding() + 112 bytes	Unknown
Noesis::DependencyObject::InternalInvalidateProperty() + 521 bytes	Unknown
Noesis::DependencyObject::ClearLocalValue() + 90 bytes	Unknown
Noesis::ItemContainerGenerator::RemoveAll() + 71 bytes	Unknown
Noesis::Panel::DisconnectFromGenerator() + 130 bytes	Unknown
Noesis::FrameworkElement::RemoveTemplatedParent() + 563 bytes	Unknown
Noesis::FrameworkElement::OnFrameworkTemplateChanged() + 178 bytes	Unknown
Noesis::FrameworkElement::OnPropertyChanged() + 397 bytes	Unknown
Noesis::DependencyObject::NotifyPropertyChanged() + 294 bytes	Unknown
Noesis::DependencyObject::InternalSetValue() + 1215 bytes	Unknown
Noesis::ClockGroup::Tick() + 2466 bytes	Unknown
Noesis::FrameworkElement::ClearFrameworkTemplate() + 70 bytes	Unknown
Noesis::ItemsPresenter::InvalidateItemsHost() + 27 bytes	Unknown
Noesis::ItemsPresenter::OnTemplatedParentChanged() + 26 bytes	Unknown
Noesis::FrameworkElement::RemoveTemplatedParent() + 563 bytes	Unknown
Noesis::FrameworkElement::RemoveTemplatedParent() + 418 bytes	Unknown
Noesis::FrameworkElement::~FrameworkElement() + 259 bytes	Unknown
Noesis::Menu::Menu() + 419 bytes	Unknown
Noesis::DependencyObject::OnDestroy() + 267 bytes	Unknown
Noesis::ClockGroup::Add() + 161 bytes	Unknown
Noesis::UIElementCollection::OnLogicalParentDestroyed() + 31 bytes	Unknown
Noesis::DependencyObject::OnDestroy() + 33 bytes	Unknown
Noesis::ClockGroup::Add() + 161 bytes	Unknown
Noesis::UIElementCollection::OnLogicalParentDestroyed() + 31 bytes	Unknown
Noesis::VisualTreeHelper::HitTest() + 14000 bytes	Unknown
Noesis::DependencyObject::OnDestroy() + 33 bytes	Unknown
Noesis::ClockGroup::Tick() + 2522 bytes	Unknown
Noesis::DependencyProperty::FindTypeProperty() + 1938 bytes	Unknown
Noesis::ContentControl::OnDestroy() + 24 bytes	Unknown
Noesis::ClockGroup::Add() + 161 bytes	Unknown
Noesis::UIElementCollection::OnLogicalParentDestroyed() + 31 bytes	Unknown
Noesis::VisualTreeHelper::HitTest() + 14000 bytes	Unknown
Noesis::DependencyObject::OnDestroy() + 33 bytes	Unknown
Noesis::ClockGroup::Tick() + 2522 bytes	Unknown
Noesis::DependencyProperty::FindTypeProperty() + 1938 bytes	Unknown
Noesis::ContentControl::OnDestroy() + 24 bytes	Unknown
Noesis::ClockGroup::Add() + 161 bytes	Unknown
Noesis::UIElementCollection::OnLogicalParentDestroyed() + 31 bytes	Unknown
Noesis::VisualTreeHelper::HitTest() + 14000 bytes	Unknown
Noesis::DependencyObject::OnDestroy() + 33 bytes	Unknown
Noesis::FrameworkElement::OnFrameworkTemplateChanged() + 240 bytes	Unknown
Noesis::FrameworkElement::OnPropertyChanged() + 397 bytes	Unknown
Noesis::ContentPresenter::OnPropertyChanged() + 21 bytes	Unknown
Noesis::DependencyObject::NotifyPropertyChanged() + 294 bytes	Unknown
Noesis::DependencyObject::InternalSetValue() + 1215 bytes	Unknown
Noesis::ClockGroup::Tick() + 2466 bytes	Unknown
Noesis::FrameworkElement::ClearFrameworkTemplate() + 70 bytes	Unknown
Noesis::ContentPresenter::OnPropertyChanged() + 106 bytes	Unknown
Noesis::DependencyObject::NotifyPropertyChanged() + 294 bytes	Unknown
Noesis::DependencyObject::InternalSetValue() + 1215 bytes	Unknown
Noesis::TextElement::SetStrokeThickness() + 220 bytes	Unknown
Noesis::ValueStorageManager::SetValueObject() + 313 bytes	Unknown
Noesis::DependencyObject::InternalSetExpression() + 577 bytes	Unknown
Noesis::DependencyObject::InternalInvalidateProperty() + 281 bytes	Unknown
Noesis::DependencyObject::InvalidateProperty() + 105 bytes	Unknown
Noesis::TemplateBindingExpression::OnTemplatedParentPropertyChanged() + 46 bytes	Unknown
Noesis::DragDrop::GetClassType() + 1291 bytes	Unknown
Noesis::DependencyObject::OnPropertyChanged() + 53 bytes	Unknown
Noesis::Visual::OnPropertyChanged() + 21 bytes	Unknown
Noesis::UIElement::OnPropertyChanged() + 32 bytes	Unknown
Noesis::FrameworkElement::OnPropertyChanged() + 65 bytes	Unknown
Noesis::Control::OnPropertyChanged() + 26 bytes	Unknown
Noesis::ContentControl::OnPropertyChanged() + 21 bytes	Unknown
Noesis::DependencyObject::NotifyPropertyChanged() + 294 bytes	Unknown
Noesis::DependencyObject::InternalSetValue() + 1215 bytes	Unknown
Noesis::FrameworkElement::SetUseLayoutRounding() + 112 bytes	Unknown
Noesis::DependencyObject::InternalInvalidateProperty() + 521 bytes	Unknown
Noesis::DependencyObject::InvalidateProperty() + 105 bytes	Unknown
Noesis::BaseTrigger::InvalidateSetters() + 279 bytes	Unknown
Noesis::DataTrigger::Invalidate() + 341 bytes	Unknown
Noesis::BaseUICollection::IsInitialized() + 86 bytes	Unknown
Noesis::DependencyProperty::IsSameValue() + 243 bytes	Unknown
Noesis::DependencyObject::OnPropertyChanged() + 36 bytes	Unknown
Noesis::Visual::OnPropertyChanged() + 21 bytes	Unknown
Noesis::UIElement::OnPropertyChanged() + 32 bytes	Unknown
Noesis::FrameworkElement::OnPropertyChanged() + 65 bytes	Unknown
Noesis::Control::OnPropertyChanged() + 26 bytes	Unknown
Noesis::ContentControl::OnPropertyChanged() + 21 bytes	Unknown
Noesis::DependencyObject::NotifyPropertyChanged() + 294 bytes	Unknown
Noesis::DependencyObject::InternalSetValue() + 1215 bytes	Unknown
Noesis::TextElement::SetStrokeThickness() + 220 bytes	Unknown
Noesis::ValueStorageManager::SetValueObject() + 313 bytes	Unknown
Noesis::DependencyObject::InternalSetExpression() + 577 bytes	Unknown
Noesis::DependencyObject::InternalInvalidateProperty() + 281 bytes	Unknown
Noesis::DependencyObject::InvalidateProperty() + 105 bytes	Unknown
Noesis::BindingExpression::InvalidateTarget() + 57 bytes	Unknown
Noesis::BindingExpression::OnNotifyPropertyChanged() + 186 bytes	Unknown
Noesis::DragDrop::GetClassType() + 1291 bytes	Unknown
>	Noesis::Delegate<void __cdecl(Noesis::BaseComponent *,Noesis::PropertyChangedEventArgs const &)>::operator()(Noesis::BaseComponent * <args_0>=0x000002b1dd79d260, const Noesis::PropertyChangedEventArgs & <args_1>={...})	C++
NotifyPropertyChangedBase::OnPropertyChanged(const char * name=0x00007ff73b3a3040)	C++
ApplicationVM::SetActiveScreen(const ActiveScreen new_selected=Dashboard)	C++
The crash doesn't happen if I comment out all ComboBoxItems and MenuItems everywhere, but it also can disappear or happen more frequently by commenting out seemingly unrelated screen parts.

I've also tried leaking all the relevant items by calling AddReference, moving them to AppResources, binding to them from VMs, and even using ItemsControls - didn't change anything. Refactoring the app to not use ComboBoxItems VMs is challenging atm, but using only MenuItems in XAML also results in a crash.

Anyway, I'm still not sure whether we do something critically incorrect, but regardless it seems like a lifetime handling issue somewhere in Noesis internals where it misses a nullptr check, so I haven't created a ticket on the Issue Tracker yet.
 
User avatar
sfernandez
Site Admin
Posts: 3013
Joined: 22 Dec 2011, 19:20

Re: Weird nullptr crash with *Items

30 Aug 2023, 16:33

Hi,

If I understood correctly you have a view model that exposes an ObservableCollection containing MenuItems or ComboBoxItems, right?
Usually this is not done like that, instead you have a list of "data items" and let the Menu/ComboBox to automatically create the corresponding container. You just need to provide the ItemTemplate (a DataTemplate or HierarchicalDataTemplate) that represents each of the items.

Anyway, let's see if we can find why it crashes in your case. How are you creating those MenuItems/ComboBoxItems? Can you share the code where you create and add them to the ObservableCollection?

Also, could you please create a ticket in our bugtracker and attach the crash dump so we can debug it?

Thanks.

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest