Waveform Editor reads a destroyed UClass in ShutdownModule on editor exit

Summary

FWaveformEditorModule::ShutdownModule calls UWaveformEditorTransformationsSettings::StaticClass()->GetFName() at WaveformEditorModule.cpp:152. On editor exit, modules shut down after every UObject has been destroyed:

  • FEngineLoop::Exit calls AppPreExit (LaunchEngineLoop.cpp:5123), which broadcasts FCoreDelegates::OnExit (LaunchEngineLoop.cpp:6940).
  • StaticExit is bound to OnExit (Obj.cpp:5873). It runs PurgeAllUObjectsOnExit and UObjectBaseShutdown (Obj.cpp:5983 and 5986).
  • FModuleManager::UnloadModulesAtShutdown runs after that (LaunchEngineLoop.cpp:5182).

By then the UClass is gone. StaticClass() returns a dangling pointer and GetFName() reads freed memory. The IsModuleLoaded(“PropertyEditor”) check does not help, because PropertyEditor is still loaded at that point.

What Type of Bug are you experiencing?

Editor

Steps to Reproduce

  1. Create a blank project with no content and no code.
  2. Enable the Waveform Editor plugin (Beta, off by default) and nothing else.
  3. Run:
    UnrealEditor-Cmd.exe .uproject -ExecCmds=QUIT_EDITOR -stompmalloc -nullrhi -RenderOffScreen -unattended -nosplash -nopause -nosound -nocrashreports

-stompmalloc makes the read of freed memory fault every time.

Expected Result

The editor exits cleanly with exit code 0 and logs LogExit: Exiting.

Observed Result

EXCEPTION_ACCESS_VIOLATION in FWaveformEditorModule::ShutdownModule, exit code 3. Without -stompmalloc the same project 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 0x0000028b068e1d98
UnrealEditor-WaveformEditor.dll!FWaveformEditorModule::ShutdownModule() [Engine\Plugins\Editor\WaveformEditor\Source\WaveformEditor\Private\WaveformEditorModule.cpp:152]
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

Skip the unregistration once UObjects are gone:
if (UObjectInitialized() && FModuleManager::Get().IsModuleLoaded(“PropertyEditor”))
Another option is to store the class name in StartupModule and unregister by that FName, so ShutdownModule never touches the UClass.

The same blank project without the Waveform Editor plugin still crashes on exit under -stompmalloc, in FClientBandwidthDebugVisualizerModule::ShutdownModule. That is a separate bug with its own report. A fix for this one tested with -stompmalloc will hit that crash next.

This bug is related to but not the same as Every editor exit reads a destroyed UObject in a Visualizer Module's ShutdownModule