Summary
UClientBandwidthDebugVisualizer is a UObject singleton held in a static TStrongObjectPtr (ClientBandwidthDebugVisualizer.cpp:43, Get() at lines 46 to 55). On exit, FBandwidthDebugDelegatesModule::ShutdownModule unloads ClientBandwidthDebugVisualizer. Its ShutdownModule then calls UClientBandwidthDebugVisualizer::Get().Shutdown() (ClientBandwidthDebugVisualizerModule.cpp:19).
This runs inside FModuleManager::UnloadModulesAtShutdown, after PurgeAllUObjectsOnExit has destroyed the object and UObjectBaseShutdown has torn down the object array. A strong pointer protects an object from garbage collection, not from the exit purge. Get() returns the destroyed object, and Shutdown() reads its members and resets the strong pointer.
What Type of Bug are you experiencing?
Editor
Steps to Reproduce
- Create a blank project with no content, no code and no extra plugins.
- Run:
UnrealEditor-Cmd.exe .uproject -ExecCmds=QUIT_EDITOR -stompmalloc -nullrhi -RenderOffScreen -unattended -nosplash -nopause -nosound -nocrashreports
Expected Result
The editor exits cleanly with exit code 0.
Observed Result
EXCEPTION_ACCESS_VIOLATION in FClientBandwidthDebugVisualizerModule::ShutdownModule, exit code 3.
Without -stompmalloc the editor loads the same modules and exits with code 0, because the freed memory still holds the old data. The read of freed memory happens on every editor exit either way.
Affects Versions
5.8
Platform(s)
Windows
For crash reports, include your callstack
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x000002be6c74afd8
UnrealEditor-ClientBandwidthDebugVisualizer.dll!FClientBandwidthDebugVisualizerModule::ShutdownModule() [Engine\Source\Runtime\Online\Experimental\ClientBandwidthDebugVisualizer\Private\ClientBandwidthDebugVisualizerModule.cpp:19]
UnrealEditor-Core.dll!FModuleManager::UnloadModule() [Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:1348]
UnrealEditor-BandwidthDebugDelegates.dll!FBandwidthDebugDelegatesModule::ShutdownModule() [Engine\Source\Runtime\Online\Experimental\BandwidthDebugDelegates\Private\BandwidthDebugDelegatesModule.cpp:20]
UnrealEditor-Core.dll!FModuleManager::UnloadModulesAtShutdown() [Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:1493]
UnrealEditor-Cmd.exe!FEngineLoop::Exit() [Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5182]
UnrealEditor-Cmd.exe!GuardedMain() [Engine\Source\Runtime\Launch\Private\Launch.cpp:204]
UnrealEditor-Cmd.exe!GuardedMainWrapper() [Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:123]
UnrealEditor-Cmd.exe!LaunchWindowsStartup() [Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:277]
UnrealEditor-Cmd.exe!WinMain() [Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:338]
Additional Notes
Suggested fix
Shut the singleton down while UObjects are still alive. For example, own it from an engine subsystem and end it in Deinitialize, or end it from an FCoreDelegates::OnPreExit handler. Then make ShutdownModule skip it when UObjectInitialized() is false.
This bug is related to but not the same as: Waveform Editor reads a destroyed UClass in ShutdownModule on editor exit