Download

Avoiding Engine From Crashing Needs 3-4 Times of Code Compilation

Hi.
I’m always facing crashes when I start to play my game. There is a problem with delegates I suppose. If I want to avoid this crash, I should re-compile my code for 3-4 times and everything works perfectly after that. I’ve reported this bug for ages and nothing has happened. What do you think?

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff

UE4Editor_Engine
UE4Editor_Regret_2040!TBaseFunctorDelegateInstance<void __cdecl(bool),FDefaultDelegateUserPolicy,<lambda_6669d0385390045a3932be9d39625d5c> >::ExecuteIfSafe() [M:\Game Related\UE4\Engine\UE_4.26\Engine\Source\Runtime\Core\Public\Delegates\DelegateInstancesImpl.h:838]
UE4Editor_Regret_2040!TMulticastDelegate<void __cdecl(bool),FDefaultDelegateUserPolicy>::Broadcast() [M:\Game Related\UE4\Engine\UE_4.26\Engine\Source\Runtime\Core\Public\Delegates\DelegateSignatureImpl.inl:955]

You’ve basically given us zero info, so it’s pretty hard to help lol. All I see is that you are accessing a nullptr. Can you post the code that causes the crash? Show us how you bind the function to the delegate, what delegate you are binding to, how does the function look like, etc…

Hi there. It’s a problem with the engine, not my code! I’ve tested my code for multiple times and I think after moving to 4.26.1, this thing popped up.
When I press play, the engine crashes, giving me this error. After restarting, I re-compile the code for 2-3 times and from then on, it works! Then when I stop playing and I play the game again, the engine crashes! Sometimes compiling once doesn’t help. I have to do it for 2-3 times. I honestly have nothing to explain here, my code is fine because the game runs fine after re-compiling the game for multiple times.

UInputManager::Alive->Flashlight.AddLambda([this](const bool KeyDown) { isFlashlightOn = !isFlashlightOn; Flashlight->SetVisibility(isFlashlightOn); });

AddLambda is the thing that has some problems. AddUObject works perfectly without needing any re-compilation.

Whereabouts is this code? Is it sitting in a constructor by any chance?

Lambda capture “this”. Are you sure that “this” is still valid at the time the lambda is invoked?

@ ACBYTES I have same code as you but with out the use of AddLambda and mine never crashes. Try what Emaer suggested make sure THIS is not null at that time. If(this != NULL).

@ACBYTES, I don’t know what your programming background is, but a common beginner mistake is to assume your code is fine, and that the engine/compiler/etc has a bug. That is statistically unlikely and will cause you to avoid analyzing your own code to figure out what you did wrong. The first thing you should do is assume your code caused the issue.

You are accessing garbage memory. The reason it works after recompiling several times is because the data you are trying to access happens to be there, and then gets overwritten by garbage afterwards.

You said you think it started after moving to 4.26.1. Revert your code checkout to the last known good commit and you should be able to confirm where the issue originated from.

2 Likes

Hi there. No, it’s in BeginPlay.

Yes! I’m sure because first of all, it’s the CharacterController and there are so many other functionalities in the class that are working. In that class, some of the delegates have been bound with AddUObject and they work while the bound lambda crashes.
Also, when you capture this, it’s surely a valid pointer… I also checked it and the results show that it’s not a nullptr. I added a comment on a word-around and the tests I did on the lambda.

This might be a temporary work-around…
Captures are passed on stack and the latest lambda scope will try to deconstruct the captured pointer. Of course, it’s not the case of keeping the object alive, it’s about keeping the pointer. Instead of capturing this, declaring a static pointer in the global scope solved the problem. In that case, the static variable is going to be kept alive until the termination of the process. Also, I captured this and I am now sure that it’s now a nullptr but still causes the crash… I decided to use this and print out it’s name on the screen. I firstly saw the name of the object, the next time, None and then I saw a malformed directory with the name of the object…

Thanks, I’m not a beginner.
Firstly, let me disprove your first comment. The Garbage_Collection problem would be viable if the pointer was being captured on construction. After one construction in the engine, the BeginPlay function gets called for multiple times as my debugs are showing me, so, I want to disprove your comment. Secondly, why are we talking about Garbage Memory? This is C++…

Yeah. Did it and it’s not.

Also, when you capture this, it’s surely a valid pointer.
At a lambda definition time - yes, at invoke time - not necessarily.
It’s valid as long as captured object is alive. Lambda doesn’t control it.

If using static solves the problem, then its clearly indicates that there is a problem with object lifetime.
Without more code is hard to say more.

Yes, that’s true. But the main thing is that the object doesn’t get deconstructed or destroyed. Firstly because I checked to make sure it’s not a nullptr and it wasn’t. Also, the character is alive in the game because first of all the player is controlling it and secondly, so many other active processes in the class are working and running fine. As I said, if the object were deconstructed, then the functions bound with AddUObject would also cause crashes. Because in the exact same instance, the AddUObject type bound delegates are working fine. There is honestly nothing else to share, this is all about it!