Software Cursor Garbage Collection Ensure

When I add a SoftwareCursor to DefaultEngine.ini [/Script/Engine.UserInterfaceSettings], the cursor works in game but there is a garbage collection ensure triggered by L3174 of GameViewportClient.cpp on the first end play in editor. Unfortunately this is breaking our spec tests. I tried this same setup in 5.5 and I do not get this ensure, so it might be an issue with 5.6? Is there a new way I need to set this up in 5.6?

Ensure Message:

LogOutputDevice: Ensure condition failed: GExitPurge || !IsGarbageCollecting() [File:D:\..\UnrealEngine\Engine\Source\Runtime\UMG\Private\Slate\SObjectWidget.cpp] [Line: 47]

SObjectWidget for ‘DefaultCursor_Sumg_C /Engine/Transient.CharlieUnrealEdEngine_0:AutomationMockGameInstance_0.DefaultCursor_Sumg_C_0’ destroyed while collecting garbage. This can lead to multiple GCs being required to cleanup the object. Possible causes might be,

1) ReleaseSlateResources not being implemented for the owner of this pointer.

2) You may just be holding onto some slate pointers on an actor that don’t get reset until the actor is Garbage Collected. You should avoid doing this, and instead reset those references when the actor is Destroyed.

[log]

Callstack:

UnrealEditor-UMG.dll!SObjectWidget::{dtor}::__l8::<lambda_1>::operator()() Line 47 C++

UnrealEditor-UMG.dll!SObjectWidget::~SObjectWidget() Line 52 C++

[Inline Frame] UnrealEditor-Engine.dll!SharedPointerInternals::TReferenceControllerBase<1>::ReleaseSharedReference() Line 227 C++

[Inline Frame] UnrealEditor-Engine.dll!SharedPointerInternals::FSharedReferencer<1>::{dtor}() Line 606 C++

UnrealEditor-Engine.dll!TSparseArray<TSetElement<TTuple<enum EMouseCursor::Type,TSharedPtr<SWidget,1>>>,TSparseArrayAllocator<TSizedDefaultAllocator<32>,FDefaultBitArrayAllocator>>::Empty(int ExpectedNumElements) Line 401 C++

[Inline Frame] UnrealEditor-Engine.dll!TSet<TTuple<enum EMouseCursor::Type,TSharedPtr<SWidget,1>>,TDefaultMapHashableKeyFuncs<enum EMouseCursor::Type,TSharedPtr<SWidget,1>,0>,FDefaultSetAllocator>::Empty(int) Line 329 C++

[Inline Frame] UnrealEditor-Engine.dll!TMapBase<enum EMouseCursor::Type,TSharedPtr<SWidget,1>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<enum EMouseCursor::Type,TSharedPtr<SWidget,1>,0>>::Empty(int) Line 243 C++

> UnrealEditor-Engine.dll!UGameViewportClient::RemoveAllViewportWidgets() Line 3174 C++

UnrealEditor-Engine.dll!UGameViewportClient::BeginDestroy() Line 443 C++

UnrealEditor-CoreUObject.dll!UObject::ConditionalBeginDestroy() Line 1263 C++

UnrealEditor-CoreUObject.dll!UnhashUnreachableObjects(bool bUseTimeLimit, double TimeLimit) Line 6095 C++

UnrealEditor-CoreUObject.dll!UE::GC::PostCollectGarbageImpl<1>(EObjectFlags KeepFlags) Line 5705 C++

UnrealEditor-CoreUObject.dll!UE::GC::FReachabilityAnalysisState::PerformReachabilityAnalysisAndConditionallyPurgeGarbage(bool bReachabilityUsingTimeLimit) Line 5907 C++

[Inline Frame] UnrealEditor-CoreUObject.dll!UE::GC::CollectGarbageInternal(EObjectFlags) Line 5462 C++

UnrealEditor-CoreUObject.dll!CollectGarbage(EObjectFlags KeepFlags, bool bPerformFullPurge) Line 6153 C++

UnrealEditor-Yggdrasil.dll!FAutomationTestWorld::Destroy() Line 239 C++

[Inline Frame] UnrealEditor-CharlieTestSuite.dll!UE::Core::Private::Function::TFunctionRefBase<UE::Core::Private::Function::TFunctionStorage<0>,void __cdecl(void)>::operator()() Line 471 C++

UnrealEditor-CharlieTestSuite.dll!FAutomationSpecBase::FSingleExecuteLatentCommand::Update() Line 2856 C++

[Inline Frame] UnrealEditor-Core.dll!IAutomationLatentCommand::InternalUpdate() Line 540 C++

UnrealEditor-Core.dll!FAutomationTestFramework::ExecuteLatentCommands() Line 628 C++

[Inline Frame] UnrealEditor-AutomationWorker.dll!FAutomationWorkerModule::ExecuteLatentCommands() Line 113 C++

UnrealEditor-AutomationWorker.dll!FAutomationWorkerModule::Tick() Line 69 C++

UnrealEditor.exe!FEngineLoop::Tick() Line 5802 C++

[Attachment Removed]

Steps to Reproduce

  1. Create a UMG widget with an image in it
  2. Add it as the default cursor in ProjectSettings->Engine->User Interface-> Software Cursors
  3. Play in Editor while attached with VS or equivalent and either stop playing or travel
  4. Ensure is triggered on L47 of SObjectWidget.cpp
    [Attachment Removed]

Hi,

You should be able to cherrypick CL#43448154 to avoid this, as we skip the ensure altogether in the editor now. It’ll still trigger at runtime if an SObjectWidget is destroyed improperly, but it sounds like this scenario is specific to PIE so I can’t imagine that will be an issue.

Best,

Cody

[Attachment Removed]