Hi! We’ve encountered a crash related to FTextureRenderTarget2DResource and probably to FDeferredUpdateResource in general on Android.
After some investigation (although we could get more data because of Android debugging issues, that’s a different topic but for some reason both in Android Studio and with VS extension I can’t debug the build on device properly - the stack is not symbolicated although the .so file definitely has all required data, I’ve double checked it) we’ve found out that in some cases a resource can be initialised and added to the deferred update list (FDeferredUpdateResource::GetUpdateList, which is a static pointer to the list element, and the addition itself happens in FDeferredUpdateResource::AddToDeferredUpdateList, while the list member itself is a member variable of FDeferredUpdateResource) and occasionally it can be immediately destroyed, while not being updated (which normally causes it’s removal from the list), so on the next cycle of update we get this crash as the pointer either of the head of the list or some element is pointing to some destroyed object.
We’ve ended up with adding a call for RemoveFromDeferredUpdateList() in the destructor of FTextureRenderTarget2DResource as it was the only resource type that caused the crash for us but ideally it should be processed on the destruction of any FDeferredUpdateResource.
Letting you know about this issue as you might will to fix it in the original engine or give some comments if you’ve already encountered it.
Best regards,
Daniil!
UPD: As there’s a call to RemovFromDeferredUpdateList in the FTextureRenderTarget2DResource::ReleaseRHI, it’s likely the case when ReleaseRHI is not called for the resource but I haven’t checked it.
Also here’s a stack for an intended crash where I’ve manually put crash-causing statement into FTextureRenderTarget2DResource destructor when it’s detected that resource is destroyed while not removed from the list:
libUnreal +0x15d96f0c FTextureRenderTarget2DResource::~FTextureRenderTarget2DResource (TextureRenderTarget2D.cpp:475) libUnreal +0x15d96f34 FTextureRenderTarget2DResource::~FTextureRenderTarget2DResource (TextureRenderTarget2D.cpp:468) libUnreal +0x15d76a08 UTexture::ReleaseResource::lambda::operator() (Texture.cpp:310) libUnreal +0x15d76a08 TEnqueueUniqueRenderCommandType<T>::DoTask (RenderingThread.h:235) libUnreal +0x15d76a08 TGraphTask<T>::ExecuteTask (TaskGraphInterfaces.h:634) libUnreal +0x0ece0e70 UE::Tasks::Private::FTaskBase::TryExecuteTask (TaskPrivate.h:504) libUnreal +0x0eceb1fc FBaseGraphTask::Execute (TaskGraphInterfaces.h:482) libUnreal +0x0eceb1fc FNamedTaskThread::ProcessTasksNamedThread (TaskGraph.cpp:779) libUnreal +0x0ecea0d0 FNamedTaskThread::ProcessTasksUntilQuit (TaskGraph.cpp:667) libUnreal +0x10c485bc RenderingThreadMain (RenderingThread.cpp:317) libUnreal +0x10c9d884 FRenderingThread::Run (RenderingThread.cpp:468) libUnreal +0x0eed2828 FRunnableThreadPThread::Run (PThreadRunnableThread.cpp:25) libUnreal +0x0ece5038 FRunnableThreadPThread::_ThreadProc (PThreadRunnableThread.h:187) libc +0x00071ae8 <unknown> libc +0x00063be0 <unknown>
Hi Daniil,
The workaround you’ve makes sense as it would ensure there are no dangling referenes in the deferred update list. However, if you are able to provide a repro project, it would be useful to pinpoint the culprit deletion which may be happening on the wrong thread.
Best regards.