Hello
we are investigating a render thread crash which happens when a player loads a savegame in our game and then changes the video settings in our in-game settings.
The actual path of the crash is curvy so I’ll try to lay it out as good as possible while focussing on common Unreal code.
The crash happens because a dynamic material instance created by View.State->GetReusableMID() in UMaterialInterface::OverrideBlendableSettings() survives a world change while still referencing a world-bound texture resource leading to a dangling pointer.
The call to OverrideBlendableSettings comes from one of our post process material which we dynamically assign and control and which references a scene capture render texture within the world. It is already a dynamic material instance when we assign it to the camera component withAddOrUpdateBlendable() but the engine creates another copy of it nonetheless with the mentioned GetReusableMID() call.
When changing the video settings the render thread eventually calls FUniformExpressionSet::FillUniformBuffer and crashes when reaching the validity checks in the “// Cache 2D texture uniform expressions.” section because of trying to access this invalid texture resource.
const UTexture* Value = nullptr;
GetTextureValue(EMaterialTextureParameterType::Standard2D, ExpressionIndex, MaterialRenderContext,MaterialRenderContext.Material,Value);
if (Value)
{
}
Value is recognised as true but the following Value->IsValidLowLevel() returns “Warning: Other object in slot”
Therefore the ensureMsgf below “// gmartin: Trying to locate UE-23902” fires
and the following checkf() below “// Trying to track down a dangling pointer bug.” crashes when trying to access Value.
The reason this dynamic material instance survives is because the only time the MIDPool is cleared is in ULocalPlayer::CleanupViewState() which is called in UEngine::LoadMap() which is NOT called when using a World->ServerTravel() > World->SeamlessTravel().
And we are using seamless travel.
The crash happens only in a shipping or debug build and not in the editor.
This is probably because we use no seamless travel in the editor PIE.
When we manually call CleanupViewState() before loading:
- the dynamic material instance is cleared and
- the crash does not happen.
I’m wondering if the view state is supposed to survive with a seamless travel or if it is a bug / uncovered edge case.
[Attachment Removed]