Description

Context

In builds with the in-game console enabled, users can use the ‘ke’ command to execute UFUNCTIONS on any object:

ke * MyFunc // run MyFunc() on ANY UObject with a ufunction with that name
ke /Script/MyModule.MyClass MyFunc // run MyFunc on all instances of AMyClass
ke /Path/To/Object MyFunc // run MyFunc on specific object

The command is handled by

UEngine::HandleKismetEventCommand

Problem

When UEngine::HandleKismetEventCommand is called with * or a class name, the function will use TObjectIterator or FThreadSafeObjectIterator to iterate objects. Both iterator types will lock the GUObjectArray.

When the target function in any way triggers FlushAsyncLoading, and the Async Loading Thread attempts to create any new UObject, the ALT will wait to acquire a lock to the GUObjectArray. The GT and ALT will be waiting for each other. See callstacks for the deadlock triggered via

ke * TestKismetEvent

where TestKismetEvent calls LoadSynchronous on a TSoftClassPtr.

Suggested Fix

We should consider that the targeted function might trigger FlushAsyncLoading. A user reported this because they use ‘ke’ to test their game code. The deadlock can be avoided by doing one pass to just gather objects (no user code) in a local array and then iterate the local array to execute the custom function on the objects.

Steps to Reproduce

See minimal repro project:

  • Start PIE in MAP_Repro in an editor session where BP_SomeOtherBP hasn’t been loaded.
    • Alternatively, start MAP_Repro from the editor in Standalone mode, to ensure the other BP hasn’t been accidentally loaded.
  • Run console command: ke * TestKismetEvent
  • Observe: Hang. Attach debugger to view the deadlock.
  • Expected: No hang

From scratch:

  • Create an actor class ATestKismetEventDeadlock with:
    • a UPROPERTY(EditDefaultsOnly) TSoftClassPtr<UObject> MyClassPtr;
    • a UFUNCTION TestKismetEvent that calls MyClassPtr.LoadSynchronous().
  • Create a blueprint based on ATestKismetEventDeadlock, BP_TestKismetEventDeadlock:
    • Add a billboard to it to visualize it
    • Set MyClassPtr to any blueprint class (make BP_Dummy, in a separate folder to avoid content browser loading it for thumbnail generation)
    • Add an instance to the map, save the map
  • Enable async loading in editor by setting in DefaultEngine.ini: [/Script/Engine.EditorStreamingSettings] s.AsyncLoadingThreadEnabled=True
  • Launch the map from editor: Play > Standalone
  • Run console command: ke * TestKismetEvent
  • Observe: Hang. Attach debugger to view the deadlock.
  • Expected: No hang
Callstack

Deadlock reproduced in 5.7. See attached repro project.

Game Thread:

 	>	UnrealEditor-Core.dll!UE::HAL::Private::FMicrosoftManualResetEvent::WaitUntilSlow(UE::FMonotonicTimePoint WaitTime) Line 68	C++
 	UnrealEditor-Core.dll!UE::ParkingLot::Private::TimedWait(const void * Address, bool(*)(void ) CanWait, void * CanWaitContext, void()(void ) BeforeWait, void * BeforeWaitContext, void()(void , UE::HAL::Private::FMicrosoftManualResetEvent &) WaitOnEvent, void * WaitOnEventContext) Line 588	C++
 	UnrealEditor-Core.dll!UE::ParkingLot::Private::WaitUntil(const void * Address, bool()(void ) CanWait, void * CanWaitContext, void()(void *) BeforeWait, void * BeforeWaitContext, UE::FMonotonicTimePoint WaitTime) Line 648	C++
 	[Inline Frame] UnrealEditor-CoreUObject.dll!UE::ParkingLot::WaitUntil(const void *) Line 80	C++
 	UnrealEditor-CoreUObject.dll!UE::FManualResetEvent::WaitUntil(UE::FMonotonicTimePoint WaitTime) Line 59	C++
 	[Inline Frame] UnrealEditor-CoreUObject.dll!UE::FManualResetEvent::WaitFor(UE::FMonotonicTimeSpan) Line 46	C++
 	UnrealEditor-CoreUObject.dll!FAsyncLoadingThread2::FlushLoading(TArrayView<int const ,int> RequestIDs) Line 11999	C++
 	UnrealEditor-CoreUObject.dll!FlushAsyncLoading(TArrayView<int const ,int> RequestIds) Line 354	C++
 	UnrealEditor-CoreUObject.dll!FlushAsyncLoading(int RequestId) Line 323	C++
 	UnrealEditor-CoreUObject.dll!LoadPackageInternal(UPackage * InOuter, const FPackagePath & PackagePath, unsigned int LoadFlags, FLinkerLoad * ImportLinker, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext, const FPackagePath * DiffPackagePath) Line 1715	C++
 	UnrealEditor-CoreUObject.dll!LoadPackage(UPackage * InOuter, const FPackagePath & PackagePath, unsigned int LoadFlags, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext, const FPackagePath * DiffPackagePath) Line 2079	C++
 	UnrealEditor-CoreUObject.dll!LoadPackage(UPackage * InOuter, const wchar_t * InLongPackageNameOrFilename, unsigned int LoadFlags, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext) Line 2055	C++
 	UnrealEditor-CoreUObject.dll!ResolveName2(UObject * & InPackage, TStringBuilderBase<wchar_t> & InOutName, bool Create, bool Throw, unsigned int LoadFlags, const FLinkerInstancingContext * InstancingContext) Line 1221	C++
 	UnrealEditor-CoreUObject.dll!StaticLoadObjectInternal(UClass * ObjectClass, UObject * InOuter, TStringView<wchar_t> InName, TStringView<wchar_t> Filename, unsigned int LoadFlags, UPackageMap * Sandbox, bool bAllowObjectReconciliation, const FLinkerInstancingContext * InstancingContext) Line 1341	C++
 	UnrealEditor-CoreUObject.dll!StaticLoadObject(UClass * ObjectClass, UObject * InOuter, TStringView<wchar_t> InName, TStringView<wchar_t> Filename, unsigned int LoadFlags, UPackageMap * Sandbox, bool bAllowObjectReconciliation, const FLinkerInstancingContext * InstancingContext) Line 1409	C++
 	UnrealEditor-CoreUObject.dll!FSoftObjectPath::TryLoad(FUObjectSerializeContext * InLoadContext) Line 818	C++
 	[Inline Frame] UnrealEditor-KismetEvtDeadlock57.dll!FSoftObjectPtr::LoadSynchronous() Line 87	C++
 	[Inline Frame] UnrealEditor-KismetEvtDeadlock57.dll!TSoftClassPtr<UObject>::LoadSynchronous() Line 977	C++
 	UnrealEditor-KismetEvtDeadlock57.dll!ATestKismetEventDeadlock::TestKismetEvent() Line 12	C++
 	UnrealEditor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 7570	C++
 	UnrealEditor-CoreUObject.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Line 2194	C++
 	UnrealEditor-Engine.dll!AActor::ProcessEvent(UFunction * Function, void * Parameters) Line 1482	C++
 	UnrealEditor-CoreUObject.dll!UObject::CallFunctionByNameWithArguments(const wchar_t * Str, FOutputDevice & Ar, UObject * Executor, bool bForceCallWithNonExec) Line 1477	C++
 	UnrealEditor-Engine.dll!UEngine::HandleKismetEventCommand(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 6568	C++
 	UnrealEditor-Engine.dll!UEngine::Exec_Dev(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 5691	C++
 	UnrealEditor-Core.dll!FExec::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 22	C++
 	UnrealEditor-Engine.dll!UEngine::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 5213	C++
 	UnrealEditor-Engine.dll!UGameEngine::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 1637	C++
 	UnrealEditor-Engine.dll!UGameViewportClient::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 3381	C++
 	UnrealEditor-Engine.dll!ULocalPlayer::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 1571	C++
 	UnrealEditor-Engine.dll!UPlayer::ConsoleCommand(const FString & Cmd, bool bWriteToLog) Line 56	C++
 	UnrealEditor-Engine.dll!APlayerController::ConsoleCommand(const FString & Cmd, bool bWriteToLog) Line 556	C++
 	UnrealEditor-Engine.dll!UConsole::ConsoleCommand(const FString & Command) Line 644	C++
 	UnrealEditor-Engine.dll!UConsole::InputKey_InputLine(FInputDeviceId DeviceId, FKey Key, EInputEvent Event, float AmountDepressed, bool bGamepad) Line 1002	C++
 	UnrealEditor-Engine.dll!UConsole::InputKey(FInputDeviceId DeviceId, FKey Key, EInputEvent Event, float AmountDepressed, bool bGamepad) Line 1782	C++
 	UnrealEditor-Engine.dll!UGameViewportClient::InputKey(const FInputKeyEventArgs & InEventArgs) Line 757	C++
 	UnrealEditor-Engine.dll!FSceneViewport::OnKeyUp(const FGeometry & InGeometry, const FKeyEvent & InKeyEvent) Line 1116	C++
 	UnrealEditor-Slate.dll!SViewport::OnKeyUp(const FGeometry & MyGeometry, const FKeyEvent & KeyEvent) Line 293	C++
 	[Inline Frame] UnrealEditor-Slate.dll!FSlateApplication::ProcessKeyUpEvent::__l2::<lambda_1>::operator()(const FArrangedWidget &) Line 5029	C++
 	UnrealEditor-Slate.dll!FEventRouter::Route<FReply,FEventRouter::FBubblePolicy,FKeyEvent,FSlateApplication::ProcessKeyUpEvent'::2'::<lambda_1>>(FSlateApplication * ThisApplication, FEventRouter::FBubblePolicy RoutingPolicy, FKeyEvent EventCopy, const FSlateApplication::ProcessKeyUpEvent::__l2::<lambda_1> & Lambda, ESlateDebuggingInputEvent DebuggingInputEvent) Line 464	C++
 	[Inline Frame] UnrealEditor-Slate.dll!FEventRouter::RouteAlongFocusPath(FSlateApplication *) Line 433	C++
 	UnrealEditor-Slate.dll!FSlateApplication::ProcessKeyUpEvent(const FKeyEvent & InKeyEvent) Line 5025	C++
 	UnrealEditor-Slate.dll!FSlateApplication::OnKeyUp(const int KeyCode, const unsigned int CharacterCode, const bool IsRepeat) Line 4993	C++

Async Loading Thread:

[Inline Frame] UnrealEditor-CoreUObject.dll!Windows::EnterCriticalSection(Windows::CRITICAL_SECTION *) Line 238	C++
[Inline Frame] UnrealEditor-CoreUObject.dll!UE::FWindowsRecursiveMutex::Lock() Line 43	C++
[Inline Frame] UnrealEditor-CoreUObject.dll!FUObjectArray::LockInternalArray() Line 1338	C++
UnrealEditor-CoreUObject.dll!FUObjectArray::AllocateUObjectIndex(UObjectBase * Object, EInternalObjectFlags InitialFlags, int AlreadyAllocatedIndex, int SerialNumber, FRemoteObjectId RemoteId) Line 257	C++
UnrealEditor-CoreUObject.dll!UObjectBase::AddObject(FName InName, EInternalObjectFlags InSetInternalFlags, int InInternalIndex, int InSerialNumber, FRemoteObjectId InRemoteId) Line 263	C++
UnrealEditor-CoreUObject.dll!UObjectBase::UObjectBase(UClass * InClass, EObjectFlags InFlags, EInternalObjectFlags InInternalFlags, UObject * InOuter, FName InName, int InInternalIndex, int InSerialNumber, FRemoteObjectId InRemoteId) Line 168	C++
UnrealEditor-CoreUObject.dll!StaticAllocateObject(const UClass * InClass, UObject * InOuter, FName InName, EObjectFlags InFlags, EInternalObjectFlags InternalSetFlags, bool bCanRecycleSubobjects, bool * bOutRecycledSubobject, UPackage * ExternalPackage, int SerialNumber, FRemoteObjectId RemoteId, FGCReconstructionGuard * GCGuard) Line 3899	C++
UnrealEditor-CoreUObject.dll!StaticConstructObject_Internal(const FStaticConstructObjectParameters & Params) Line 4963	C++
[Inline Frame] UnrealEditor-CoreUObject.dll!NewObject(UObject *) Line 1951	C++
UnrealEditor-CoreUObject.dll!FAsyncPackage2::CreateUPackage() Line 11337	C++
UnrealEditor-CoreUObject.dll!FAsyncPackage2::InitializeLinkerLoadState(const FLinkerInstancingContext * InstancingContext) Line 6854	C++
UnrealEditor-CoreUObject.dll!FAsyncLoadingThread2::CreateAsyncPackagesFromQueue(FAsyncLoadingThreadState2 & ThreadState, bool bForceExitForGarbageCollect) Line 5768	C++
UnrealEditor-CoreUObject.dll!FAsyncLoadingThread2::Run() Line 10476	C++
UnrealEditor-Core.dll!FRunnableThreadWin::Run() Line 159	C++
UnrealEditor-Core.dll!FRunnableThreadWin::GuardedRun() Line 79	C++

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-373054 in the post.

0
Login to Vote

Fixed
Fix Commit52512365
CreatedApr 8, 2026
ResolvedApr 8, 2026
UpdatedMay 15, 2026
View Jira Issue