Description

Since UE5.4, it has been reported that if there's a class derived from UEditorUtilitySubsystem, the program crashes when the editor exits. This is because the code added in CL30853505 accesses freed memory.

In void UEditorUtilitySubsystem::Initialize(FSubsystemCollectionBase& Collection), the following code receives RunTaskCommandObject.

RunTaskCommandObject = IConsoleManager::Get().RegisterConsoleCommand(
	TEXT("RunTask"),
	TEXT(""),
	FConsoleCommandWithWorldArgsAndOutputDeviceDelegate::CreateUObject(this, &UEditorUtilitySubsystem::RunTaskCommand),
	ECVF_Default
);

But if you create a subclass of EditorUtilitySubsystem, void UEditorUtilitySubsystem::Initialize(FSubsystemCollectionBase& Collection) is called multiple times and it causes duplicate command registration. To prevent this duplicate registration, Engine\Source\Runtime\Core\Private\HAL\ConsoleManager.cpp(2830) releases redundant objects and keep the last one;

// Replace console command with the new one and release the existing one.
// This should be safe, because we don't have FindConsoleVariable equivalent for commands.
ConsoleObjects.Add( Name, Cmd );
ExistingCmd->Release();

This results make the pointer owned by early initialized UEditorUtilitSubsystem a dangling pointer.

And now, when the editor exits, void UEditorUtilitySubsystem::Deinitialize() calls UnregisterConsoleObject with this dangling pointer;

IConsoleManager::Get().UnregisterConsoleObject(RunTaskCommandObject);

This ends up to call FString FConsoleManager::FindConsoleObjectName(const IConsoleObject* InVar) const and hit dangling pointer access added by CL30853505;

// if we didn't find one, and it has a parent, then give that a try
>;if (InVar->GetParentObject() != nullptr)

 

Steps to Reproduce
  1. Create a C++ Blank project.
  2. Add a new sub class of ​UEditorUtilitySubsystem.
  3. Compile and restart the Unreal Editor.
  4. Close the editor.
  5. Confirm a crash.

The repro project is available from the attachment. Just open the project then close the editor.

Callstack

 

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffff00000028
UnrealEditor_Core!FConsoleManager::FindConsoleObjectName() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\ConsoleManager.cpp:2888]
UnrealEditor_Core!FConsoleManager::UnregisterConsoleObject() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\ConsoleManager.cpp:2116]
UnrealEditor_Blutility!UEditorUtilitySubsystem::Deinitialize() [D:\build\++UE5\Sync\Engine\Source\Editor\Blutility\Private\EditorUtilitySubsystem.cpp:103]
UnrealEditor_Engine!FSubsystemCollectionBase::Deinitialize() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Subsystems\SubsystemCollection.cpp:201]
UnrealEditor_UnrealEd!UEditorEngine::PreExit() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1471]
UnrealEditor!FEngineLoop::Exit() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5087]
UnrealEditor!GuardedMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:194]
UnrealEditor!GuardedMainWrapper() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:118]
UnrealEditor!LaunchWindowsStartup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:258]
UnrealEditor!WinMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:298]
UnrealEditor!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll

 

Have Comments or More Details?

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

0
Login to Vote

Fixed
ComponentUE - Editor - UI Systems - UMG
Affects Versions5.4
Target Fix5.5
Fix Commit34744557
CreatedJun 18, 2024
ResolvedJun 28, 2024
UpdatedJul 21, 2024
View Jira Issue