Crashes due to TypeClass objects getting garbage collected after loading a new world
Posted: 05 Jul 2023, 10:14
Hello,
first off, important to note is that this issue only happens in packaged builds. We tried forcing it in PIE or standalone mode, but it wont happen.
Our HUD uses the <noesis:Brush.Shader /> extension to load in UE materials. Also, there are DataEventTriggers hooked up with UE events on the view model of the HUD for triggering storyboard animations.
When a transition to new level happens, Player controller and HUD get recreated and the game crashes for two possible reasons:
1) UMaterialInterface pointers stored in 'MaterialMap' and the NoesisTypClass objects in NoesisTypeClass.cpp were no longer valid.
2) The UFunction pointer attached to UObject::StaticClass() in NoesisTypeClass.cpp, line 2497 was no longer valid. Executing the event crashed the game
'USomeRandomComponent::FAction_DelegateWrapper' can be anything, as this is were the data is messed up.
To further verify that those objects were in fact garbage-collected, we placed breakpoints in various functions within NoesisTypeClass.cpp shortly before the crash happened.
MaterialMap was filled with garbage data and the functions added to UObject::StaticClass() as well.
Is this a known issue or are we doing something wrong here, for example in terms of object ownership?
As a temporary workaround to these issues we added a small gameinstance subsystem for keeping counted references of material and UFunction objects.
We think the way objects are currently cached without the UPROPERTY() specifier in NoesisTypeClass.cpp should be reworked, as it is extremely risky. Also, there is no point
where MaterialMap data gets removed, except when the Noesis Module is unloaded.
first off, important to note is that this issue only happens in packaged builds. We tried forcing it in PIE or standalone mode, but it wont happen.
Our HUD uses the <noesis:Brush.Shader /> extension to load in UE materials. Also, there are DataEventTriggers hooked up with UE events on the view model of the HUD for triggering storyboard animations.
When a transition to new level happens, Player controller and HUD get recreated and the game crashes for two possible reasons:
1) UMaterialInterface pointers stored in 'MaterialMap' and the NoesisTypClass objects in NoesisTypeClass.cpp were no longer valid.
Code: Select all
FD3D12CommandContextBase::RHIBeginDrawingViewport(FRHIViewport *,FRHITexture *) D3D12Viewport.cpp:876
CallbackCreateMaterialWrapper(Symbol) NoesisTypeClass.cpp:2848
<unknown> 0x00007ffcc9323ac8
...
<unknown> 0x00007ffcc940751e
UNoesisXaml::LoadXaml() NoesisXaml.cpp:33
UNoesisInstance::InitInstance() NoesisInstance.cpp:499
UNoesisInstance::NativeConstruct() NoesisInstance.cpp:1746
UNoesisInstance::OnWidgetRebuilt() NoesisInstance.cpp:1163
UWidget::TakeWidget_Private(TFunctionRef<TSharedPtr<SObjectWidget,1> __cdecl(UUserWidget *,TSharedRef<SWidget,1>)>) Widget.cpp:997
...
Code: Select all
[Inlined] operator&(EFunctionFlags,EFunctionFlags) Script.h:173
[Inlined] UFunction::HasAnyFunctionFlags(EFunctionFlags) Class.h:1832
UObject::ProcessEvent(UFunction *,void *) ScriptCore.cpp:2055
[Inlined] TScriptDelegate<FWeakObjectPtr>::ProcessDelegate(void *) ScriptDelegates.h:289
TMulticastScriptDelegate<FWeakObjectPtr>::ProcessMulticastDelegate<UObject>(void *) ScriptDelegates.h:579
USomeRandomComponent::FAction_Delegate(const TMulticastScriptDelegate<FWeakObjectPtr> &) USomeRandomComponent.gen.cpp:106
UViewModel_HUD::PlayShowAnimation() UViewModel_HUD.cpp:63
...
To further verify that those objects were in fact garbage-collected, we placed breakpoints in various functions within NoesisTypeClass.cpp shortly before the crash happened.
MaterialMap was filled with garbage data and the functions added to UObject::StaticClass() as well.
Is this a known issue or are we doing something wrong here, for example in terms of object ownership?
As a temporary workaround to these issues we added a small gameinstance subsystem for keeping counted references of material and UFunction objects.
We think the way objects are currently cached without the UPROPERTY() specifier in NoesisTypeClass.cpp should be reworked, as it is extremely risky. Also, there is no point
where MaterialMap data gets removed, except when the Noesis Module is unloaded.