Editor Crash While Loading Assets

We’re encountering an editor crash due to us hitting a check on Unreal 5.4.3. In summary, a blueprint event is occurring while another object is in PostLoad.

https://github.com/EpicGames/UnrealEngine/blob/5\.4/Engine/Source/Runtime/CoreUObject/Private/UObject/ScriptCore.cpp\#L1977

However, we’re not in control when that event is processed. It is caused from a sequence of events starting from an async load.

1. An initializing subsystem starts an async load of some assets.

2. That load requires a post-load

3. During that async load process, the editor sends progress updates

4. Among other things, that requires a block on the main thread until the rendering thread is idle.

5. That’s when we hit the check. At that point, the main thread goes back to processing the task graph, which needs to call UnrealScript.

We’ve implemented a workaround in AsyncCompilationHelpers::Update.

void FAsyncCompilationNotification::Update(int32 NumJobs)

{

#if WITH_EDITOR

check(IsInGameThread());

// workaround begins

if (FUObjectThreadContext::Get().IsRoutingPostLoad)

{

return;

}

// workaround ends

// Use a lambda to only for progress message in code-path where it’s needed

}

We saw a similar check in a few places, such as in AsyncCompilationHelpers::FinishCompilation, which avoids showing progress if a UObject is in the middle of a PostLoad.

We’d like to understand

1. Is this a reasonable workaround?

2. Have you seen any similar issues, and made fixes?

Steps to Reproduce
It should be possible to reproduce this by putting a lot of UObject event calls in the task graph while async loading a lot of skeletal meshes.

This was the stack trace we were seeing:

Assertion failed: !FUObjectThreadContext::Get().IsRoutingPostLoad [File:c:\fbroot\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp] [Line: 1993]

Cannot call UnrealScript (ProprietarySubsystem /Engine/Transient.UnrealEdEngine_0:GameInstance_0.ProprietarySubsystem_0 - Function /Script/Online.ProprietarySubsystemBase:OnStatusChanged) while PostLoading objects

UnrealEditor-CoreUObject.dll!UObject::ProcessEvent() [C:\fbroot\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1993]

<Removed proprietary frame>

<Removed proprietary frame>

<Removed proprietary frame>

<Removed proprietary frame>

<Removed proprietary frame>

<Removed proprietary frame>

UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread() [C:\fbroot\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:760]

UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksUntilQuit() [C:\fbroot\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:651]

UnrealEditor-Core.dll!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete() [C:\fbroot\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2122]

UnrealEditor-D3D12RHI.dll!FGraphEvent::Wait() [C:\fbroot\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:974]

UnrealEditor-D3D12RHI.dll!FD3D12SyncPoint::Wait() [C:\fbroot\Engine\Source\Runtime\D3D12RHI\Private\D3D12Submission.cpp:928]

UnrealEditor-D3D12RHI.dll!FD3D12Device::BlockUntilIdle() [C:\fbroot\Engine\Source\Runtime\D3D12RHI\Private\D3D12Device.cpp:578]

UnrealEditor-D3D12RHI.dll!FD3D12Adapter::BlockUntilIdle() [C:\fbroot\Engine\Source\Runtime\D3D12RHI\Private\D3D12Adapter.cpp:1762]

UnrealEditor-D3D12RHI.dll!FD3D12Viewport::Resize() [C:\fbroot\Engine\Source\Runtime\D3D12RHI\Private\D3D12Viewport.cpp:490]

UnrealEditor-D3D12RHI.dll!FD3D12Viewport::Init() [C:\fbroot\Engine\Source\Runtime\D3D12RHI\Private\Windows\WindowsD3D12Viewport.cpp:225]

UnrealEditor-D3D12RHI.dll!FD3D12DynamicRHI::RHICreateViewport() [C:\fbroot\Engine\Source\Runtime\D3D12RHI\Private\D3D12Viewport.cpp:835]

UnrealEditor-SlateRHIRenderer.dll!FSlateRHIRenderer::CreateViewport() [C:\fbroot\Engine\Source\Runtime\SlateRHIRenderer\Private\SlateRHIRenderer.cpp:468]

UnrealEditor-SlateCore.dll!SWindow::ShowWindow() [C:\fbroot\Engine\Source\Runtime\SlateCore\Private\Widgets\SWindow.cpp:1412]

UnrealEditor-Slate.dll!FSlateApplication::AddWindowAsNativeChild() [C:\fbroot\Engine\Source\Runtime\Slate\Private\Framework\Application\SlateApplication.cpp:2200]

UnrealEditor-Slate.dll!FSlateNotificationManager::CreateStackForArea() [C:\fbroot\Engine\Source\Runtime\Slate\Private\Framework\Notifications\NotificationManager.cpp:157]

UnrealEditor-Slate.dll!FSlateNotificationManager::AddNotification() [C:\fbroot\Engine\Source\Runtime\Slate\Private\Framework\Notifications\NotificationManager.cpp:217]

UnrealEditor-StatusBar.dll!SStatusBar::UpdateProgressStatus() [C:\fbroot\Engine\Source\Editor\StatusBar\Private\SStatusBar.cpp:950]

UnrealEditor-StatusBar.dll!UStatusBarSubsystem::UpdateProgressNotification() [C:\fbroot\Engine\Source\Editor\StatusBar\Private\StatusBarSubsystem.cpp:716]

UnrealEditor-Slate.dll!FSlateNotificationManager::UpdateProgressNotification() [C:\fbroot\Engine\Source\Runtime\Slate\Private\Framework\Notifications\NotificationManager.cpp:247]

UnrealEditor-Engine.dll!FAsyncCompilationNotification::Update() [C:\fbroot\Engine\Source\Runtime\Engine\Private\AsyncCompilationHelpers.cpp:69]

UnrealEditor-Engine.dll!FSkinnedAssetCompilingManager::AddSkinnedAssets() [C:\fbroot\Engine\Source\Runtime\Engine\Private\SkinnedAssetCompiler.cpp:294]

UnrealEditor-Engine.dll!USkinnedAsset::PostLoad() [C:\fbroot\Engine\Source\Runtime\Engine\Private\SkinnedAsset.cpp:138]

UnrealEditor-Engine.dll!USkeletalMesh::PostLoad() [C:\fbroot\Engine\Source\Runtime\Engine\Private\SkeletalMesh.cpp:3436]

UnrealEditor-CoreUObject.dll!UObject::ConditionalPostLoad() [C:\fbroot\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp:1306]

UnrealEditor-CoreUObject.dll!FAsyncPackage::PostLoadDeferredObjects() [T:\p4\pole\dev-main\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp:7062]

UnrealEditor-CoreUObject.dll!FAsyncLoadingThread::ProcessLoadedPackages() [T:\p4\pole\dev-main\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp:4795]

UnrealEditor-CoreUObject.dll!FAsyncLoadingThread::TickAsyncLoading() [T:\p4\pole\dev-main\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp:5020]

UnrealEditor-CoreUObject.dll!FAsyncLoadingThread::FlushLoading() [T:\p4\pole\dev-main\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp:7573]

UnrealEditor-CoreUObject.dll!FlushAsyncLoading() [C:\fbroot\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncPackageLoader.cpp:295]

UnrealEditor-Engine.dll!FStreamableHandle::WaitUntilComplete() [C:\fbroot\Engine\Source\Runtime\Engine\Private\StreamableManager.cpp:432]

<Removed proprietary frame>

<Removed proprietary frame>

<Removed proprietary frame>

<Removed proprietary frame>

UnrealEditor-Engine.dll!FSubsystemCollectionBase::AddAndInitializeSubsystem() [C:\fbroot\Engine\Source\Runtime\Engine\Private\Subsystems\SubsystemCollection.cpp:261]

UnrealEditor-Engine.dll!FSubsystemCollectionBase::Initialize() [C:\fbroot\Engine\Source\Runtime\Engine\Private\Subsystems\SubsystemCollection.cpp:149]

UnrealEditor-Engine.dll!UWorld::InitWorld() [C:\fbroot\Engine\Source\Runtime\Engine\Private\World.cpp:2096]

UnrealEditor-UnrealEd.dll!UEditorEngine::PostCreatePIEWorld() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:2399]

UnrealEditor-Engine.dll!UGameInstance::InitializeForPlayInEditor() [C:\fbroot\Engine\Source\Runtime\Engine\Private\GameInstance.cpp:369]

UnrealEditor-UnrealEd.dll!UEditorEngine::CreateInnerProcessPIEGameInstance() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:2969]

UnrealEditor-UnrealEd.dll!UEditorEngine::OnLoginPIEComplete_Deferred() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1600]

UnrealEditor-UnrealEd.dll!UEditorEngine::CreateNewPlayInEditorInstance() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1863]

UnrealEditor-UnrealEd.dll!UEditorEngine::StartPlayInEditorSession() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:2882]

UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequestImpl() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1177]

UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequest() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1078]

UnrealEditor-UnrealEd.dll!UEditorEngine::Tick() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1905]

UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick() [C:\fbroot\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:553]

UnrealEditor.exe!FEngineLoop::Tick() [C:\fbroot\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5983]

UnrealEditor.exe!GuardedMain() [C:\fbroot\Engine\Source\Runtime\Launch\Private\Launch.cpp:180]

UnrealEditor.exe!GuardedMainWrapper() [C:\fbroot\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:118]

UnrealEditor.exe!LaunchWindowsStartup() [C:\fbroot\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:258]

UnrealEditor.exe!WinMain() [C:\fbroot\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:298]

UnrealEditor.exe!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]

KERNEL32.DLL!UnknownFunction

Hello Marc,

Sorry for delayed response. I had a chance to briefly look at the code locations you shared in your question and the check() it is hitting in the ScriptCore.cpp

Your workaround seems correct as that will avoid doing any work when the post load is ongoing. Without knowing about the internals of the proprietary subsystem you are using, it will be hard to tell if there is any different route you may take to avoid this issue altogether.

Feel free to reach out should you have any further questions.

Regards,

Vedang