Pure virtual function beign called while application was running (GIsRunning == 1)

Hello, this one is a bit strange. And I really don’t know how to resolve it. Randomly, on game restart I get this crash. And I can’t possibly know what is causing it. I am not calling any pure virtual functions at all, as I haven’t created any.

This is only happening when I run game as standalone (or Right click on UE file → Launch Game) and when I click to restart the game, because the characted died. This never happened in editor, and it always happen on level restart.

Here is how I restart the game.

Crash popup:
image

These are the logs.

Fatal error: [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsPlatformMisc.cpp] [Line: 439] Pure virtual function being called

UnrealEditor_Core!PureCallHandler() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsPlatformMisc.cpp:441]
VCRUNTIME140
UnrealEditor_Engine!UE::Shader::EvaluateParameter() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Shader\Preshader.cpp:440]
UnrealEditor_Engine!UE::Shader::EvaluatePreshader() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Shader\Preshader.cpp:892]
UnrealEditor_Engine!FUniformExpressionSet::FillUniformBuffer() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Materials\MaterialUniformExpressions.cpp:857]
UnrealEditor_Engine!`FUniformExpressionCacheAsyncUpdater::Update'::`2'::<lambda_1>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Materials\MaterialRenderProxy.cpp:144]
UnrealEditor_Engine!TGraphTask<TFunctionGraphTaskImpl<void __cdecl(void),0> >::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1265]
UnrealEditor_Core!`LowLevelTasks::FTask::Init<`FTaskGraphCompatibilityImplementation::QueueTask'::`5'::<lambda_1> >'::`11'::<lambda_1>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\Task.h:499]
UnrealEditor_Core!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<`LowLevelTasks::FTask::Init<`FTaskGraphCompatibilityImplementation::QueueTask'::`5'::<lambda_1> >'::`11'::<lambda_1>,0>::CallAndMove() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\TaskDelegate.h:171]
UnrealEditor_Core!LowLevelTasks::FTask::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\Task.h:627]
UnrealEditor_Core!LowLevelTasks::FScheduler::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:150]
UnrealEditor_Core!LowLevelTasks::FScheduler::TryExecuteTaskFrom<LowLevelTasks::TLocalQueueRegistry<1024>::TLocalQueue,&LowLevelTasks::TLocalQueueRegistry<1024>::TLocalQueue::DequeueGlobal,0>() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:350]
UnrealEditor_Core!LowLevelTasks::FScheduler::WorkerMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:378]
UnrealEditor_Core!UE::Core::Private::Function::TFunctionRefCaller<`LowLevelTasks::FScheduler::CreateWorker'::`2'::<lambda_1>,void __cdecl(void)>::Call() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Templates\Function.h:480]
UnrealEditor_Core!FThreadImpl::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\Thread.cpp:69]
UnrealEditor_Core!FRunnableThreadWin::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:149]

Any help is appreciated

OK, so I managed to resolve this one.
TL;DR Issue was caussed by BlueprintImplementableEvent that was defined in C++ class of my Pawn, and used in Blueprints. That event was called in tick method and was called early, which was causing the crash.

Now detailed explanation on what happened. This is important for those who encounter similar issues, since I see a lots of people had this one.

Behavior:

  • It only happens when new level is loaded or restarted. I’m making 2D platformer that has a lots of levels, and therefore levels are changing a lot.
  • It would manifest ONLY on the compiled / standalone build. Either packaged project, project that is ran using runnable BAT file, or when you right click on .uproject file and choose run game.

How to reproduce?

  • I already had my level restart logic (image above in my original post).
  • So, what I did, is that I waited for level to load (yes I have the logic that knows exactly when level is fully loaded), and then I would wait for 2 seconds and restart the level. This would cause infinite restart loop two seconds after level is loaded.
  • I would let the game restart itself for infinite number of time. In no more than 3-4 minutes, issue would be reproduced.

How to identify the issue
After I have made sure I have proper step to reproduce, I went to these steps.

My levels are devided in four parts.

  • Persistent level containing player spawn and collision where player should stand
  • Map contain graphical assets
  • Collision assets
  • Logical assets (traps for the platformer, AI chars… etc)

So I started removing things.

  • I removed levels, one by one, until I reached only persistent level. It would take more time to reproduce the issue, and I realized that it was either my character or collision box. Since collision box is a simple collision, it was obvious character was wrong.

  • I changed default pawn in the game mode to default UE pawn. And issue would not be manifested after 30 minutes of restarting.

  • Then I removed whole logic from Tick() and BeginPlay() methods inside of my pawn, and set my own pawn back in the game mode. So it was like it was before. My own pawn was the default one.

Issue would not be reproduced for another 30 mins.

I brought back logic inside of BeginPlay(), and issue was not reproduced again, which means problem was inside of the Tick() method.

Then I commented one by one thing in the Tick() until I was again unable to reproduce the issue. Fortunately my Tick() function was really really simple, and I came to the BlueprintImplementableEvent that is called when animation of my pawn is changed.

How did I resolve the issue?
Well, I already mentioned I have the logic to know when my level is finished loading. I used that logic to change the isLevelLoaded boolean value to true when it’s done. When IsLevelLoaded is false, there is no logic done in the Tick() at all.

Everything works like a charm now.

Moral of the story
Use event based logic for your games, avoid Tick() as much as possible. When you need it, keep it simple. I was lazy, I admit, but this game is so low and cheap, I got away with it. But, I will refactor it in the future.

How do I know when level is loaded?
Get ready for terrible code. Yes, this is how I do it. I’m not proud of it, but it gets the job done for me. I will also have to revisit this in the future. As I mentioned, my maps are devided in 4 parts, and I load (not counting persistent level as it’s automatically loaded) those parts in sequence in my level blueprint. When that is done, I notify game instance that level is loaded. It looks like this:

LevelLoaded is actor function library and looks like this:

As I said, terrible code, and I’ll make sure to refactor this in the future and use proper way to load everything.

Sorry fo long post, all I wanted is to help others in case they have similar issue like mine.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.