Frequent memory access crashes in low level engine code (Slate/Garbage collection)

Posting this here as honestly I have no better place to go.

I’ve been having the editor crash on me regularly for a while now, the crashes are always related to accessing already-freed memory, often deep within C++ destructors of base engine types. At a higher level, they tend to be within Slate or garbage collection code. The specific place however is unpredictable, though it most often happens when triggering a significant action in the editor, such as stopping PIE, compiling a blueprint, etc.

I have a lot of experience tracking down crashes in C++, but this is beyond me. As far as I can tell it doesn’t relate to any particular class/object, although generally when the debugger breaks all the memory in question has already been garbled, and the call stack is pretty much useless because it’s in a Slate prepass or GC with barely any meaningful context. It made me suspect possible hardware memory corruption, but the thing is this happens in one specific project only. That project is using the same engine version as I use for other projects (in fact it began in 4.17 and persists now with 4.18), and is by no means the most resource intensive of the projects I’m working on.

Has anyone else seen something like this? Does anyone have any suggestions of what could conceivably cause this kind of issue, or how to go about tracking it down? Guesses and wild speculation welcome - it’s really becoming a huge pain. If I can’t sort it I’ll have to recreate the project from scratch and gradually move things across, which isn’t going to be fun.

I have been having the exact same issues, but only since upgrading to 15.5.3! I am unsure what version of visual studio 2017 before upgrading, but I did some digging around and found this:
https://developercommunity.visualstu…rect-code.html

the topic there suggests that 15.5.3 fixes the issue, but it doesn’t (for me).

I have nearly identical issues as you described in both Development Editor and DebugGame Editor. Crashes within GC, Slate and TBB memory calls. I’m awaiting Debug Editor to finish building, but it honestly feels like going down from Development Editor to DebugGame Editor caused the crashes more frequently. I will let you know how Debug Editor crashes, please let me know if you ran into any fix for the issue.

Update:
Debug Editor configuration crashes just like the rest. Does not seem to disable optimization. I’m going to install visual studio preview and i’ll let you know how that goes.

On Slate, never use “raw” values.
For example, many people do things like this in Slate UI code:



void SetTextFieldByID(uint32 ColumnID, FString NewField);


When smart pointer is safer to use:



void SetColumnTypeByID(TSharedPtr<uint32> ColumnID, TSharedPtr<FString> NewType) {
     TSharedPtr<IPropertyHandle> ColumnHandle = ColumnTypes->GetChildHandle(ColumnID.ToSharedRef().Get()).ToSharedRef();
    //...
}


Also a lot of people pass references of owner widgets to a child widget, like this:



TSharedRef<SThisWidget>(this);   // This is going to crash someday somewhere...


But that will cause crashes. Epic provides that “AsShared()” function to avoid this:



TSharedRef<SThisWidget> ThisShared = StaticCastSharedRef<SThisWidget>(AsShared());

//...

SAssignNew(MyChildWidget,SComboBoxWidget)
            .Owner(ThisShared)


On class destructor always reset your Slate stuff:



SThisWidget::~SThisWidget() {
    SomeStuff.Reset();
    SomeArrayPtr.Reset();
}


And, something somewhere in your project, may have this:



virtual void BeginDestroy() override;

void UMyObject::BeginDestroy() {
    SomeArray.Empty();
}


That works fine, but without a call to “Super::BeginDestroy()” things gonna crash randomly without any easy way to track exactly what is going on; making you believe this was a crash because of bad programming inside low level engine code that VisualStudio is pointing fingers at, but in reality that’s not the case.

BrUnO XaVIeR: Thanks for the tips but I haven’t yet dealt with slate, I don’t have any slate code in my project. The issue we are running into seems related to the compiler generating incorrect code. I can’t confirm that kamrann started running into these issues after upgrading visual studio to 15.5.3 but I experience nearly identical problems that he’s outlined, only after upgrading to 15.5.3.

I do frequenlty use TSharedPtr however, make new UObject’s etc but the editor crashes reliably once its entered PIE even without any objects in the world that are of my own creation. I’ve also made no edits to the engine and have used the same 4.18 release running over night without crashes prior to upgrading visual studio. While I’m not saying its impossible that I’m some how causing the issue (which i’ve already spent days on the assumption I was), I’m now leaning towards this being a compiler issue.

I’m currently building on visual studio 15.6 preview 2 and will let you know how that goes… otherwise will be downgrading to pre 15.5 visual studio.

Update:

I’ve crashed twice now in 15.6 preview 2 build, compiled with my project. but it lasted much longer. I was able to enter and exit PIE countless times, it was only when I moved to post about it working where it then crashed. I am somewhat unsure if all the build data from pre 15.6 build was blown away, the callstack ended in grayed out functions so I’ve cleaned the solution, building from UE4.sln and will update further (10 minutes or so). It looked somewhat promising. The first time it crashed was during particles, a call to FMallocTBB, then the second time was in some other slate operation.

Update 2:

After a clean build using 15.6 preview 2 the editor no longer crashes on the default cube skybox level, but still experience crashes similar to what kamrann experiences with low level api calls invovling delegates, memory FMemory::Memset not in-my-project-code but once its running. I’m doing lots of stuff with TSharedPtr, UObjects / UInterfaces then a lot of c++17 constexpr and templating behind that. Since its not crashing on the default level i’m going to take a closer look at my code. If you have had any success kamrann in identifying the issue, or if you have any more tips BrUnO please let me know! all appreciated.

Interesting about the VC++ bug, thanks for the heads up. I’ll look into it, but my gut feeling is that’s probably not the cause of my issues. Also, I’m still on 15.4.1.

Trying to get more info with a DebugEditor build is something I intend to do, just haven’t got around to it as I haven’t used a source engine build in quite a while. The crashes are always so deep in memory deallocation though that I’m not sure it will reveal all that much more. If I find anything at any point, I’ll report back here.

kamrann, I’ve investigated this further and have fixed the issue within my project. While I’m not dealing with Slate as bruno assumed, and I have yet to exactly determine what caused the exact issue we both experienced I believe that he was right to point out some things to look into. What fixed the issue for me was the creator update caused the failure to be more controllably late and I was at least able to identify where my code was going wrong. The suspect code was doing a lot with TScriptInterface, TSharedPtr and TWeakObjectPtr and the root of the fix was I noticed one crutial element of an array was not initialized to a value. I mistakenly had for(int32 i = arr.Num()-1;i!=0;–i){…} when it should have been >=0 so that one uninitialized bit of memory threw off stuff so that it was unpredictable as to what was actually going on at runtime and utlimately i’m guessing wound up violating something of TSharedPtr or TWeakObjectPtr or TScriptInterface or even just having an invalid UObject* reference, which is the only thing that makes sense to me. It seems like some how setting TWeakObjectPtr to an invalid pointer gets it some how in GC registration and eventually fails at some point down the line (it’s interesting the amount of checks going on to prevent such a thing).

So long story short, I would take the notes of what bruno mentioned and also remember to check the fields/members of your types to make sure they are properly initialized (specifically those of UObject* which will not initialize as TWeakObjectPtr) with the constructor being used.