Description

FNiagaraParameterStore::UnbindAll() may be called from both GameThread and RenderingThread.
Each may modify the same Binding array, it causes infrequent crashes.

In my environment, I was able to reproduce the crash with a fairly high probability by using the log output code described in the repro step.

Placing a CriticalSection at UnbindAll work around this issue.

FCriticalSection GNiaagraParameterStoreUnbindingCS; // workaround

void FNiagaraParameterStore::UnbindAll()
{
	FScopeLock Lock(&GNiaagraParameterStoreUnbindingCS); // workaround
	UnbindFromSourceStores();
	for (TPair<FNiagaraParameterStore*, FNiagaraParameterStoreBinding>& Binding : Bindings)
	{
		Binding.Value.Empty(Binding.Key, this);
	}
	Bindings.Empty();
}

Steps to Reproduce

1. Add the logging code to the FNiagaraParameterStoreBinding

FORCEINLINE_DEBUGGABLE void FNiagaraParameterStoreBinding::Empty(FNiagaraParameterStore* DestStore, FNiagaraParameterStore* SrcStore)
{
	if (DestStore)
	{
		//UE_LOG(LogNiagara, Log, TEXT("Remove Src Binding: Src: 0x%p - Dst: 0x%p"), SrcStore, DestStore);
		UE_LOG( LogTemp, Log, TEXT("Binding:Empty %p Src: %p : %s"), DestStore, SrcStore, IsInRenderingThread()?TEXT("Render"):TEXT("Game") ); //add this
		DestStore->GetSourceParameterStores().RemoveSingleSwap(SrcStore, false);
	}
	DestStore = nullptr;
	ParameterBindings.Reset();
	InterfaceBindings.Reset();
	UObjectBindings.Reset();
}

2. Open attached project on 4.26 [Link Removed]
3. Start PIE

Callstack
>	[Inline Frame] UE4Editor-Niagara.dll!TArray<FNiagaraParameterStore *,TSizedDefaultAllocator<32>>::RangeCheck(int Index) Line 674	C++
 	[Inline Frame] UE4Editor-Niagara.dll!TArray<FNiagaraParameterStore *,TSizedDefaultAllocator<32>>::operator[](int) Line 718	C++
 	UE4Editor-Niagara.dll!FNiagaraParameterStore::UnbindFromSourceStores() Line 463	C++
 	UE4Editor-Niagara.dll!FNiagaraParameterStore::UnbindAll() Line 359	C++
 	UE4Editor-Niagara.dll!FNiagaraParameterStore::~FNiagaraParameterStore() Line 196	C++
 	UE4Editor-Niagara.dll!FNiagaraEmitterInstance::~FNiagaraEmitterInstance() Line 182	C++
 	[Inline Frame] UE4Editor-Niagara.dll!SharedPointerInternals::FReferenceControllerOps<1>::ReleaseSharedReference(SharedPointerInternals::FReferenceControllerBase * ReferenceController) Line 282	C++
 	[Inline Frame] UE4Editor-Niagara.dll!SharedPointerInternals::FSharedReferencer<1>::{dtor}() Line 469	C++
 	[Inline Frame] UE4Editor-Niagara.dll!DestructItems(TSharedRef<FNiagaraEmitterInstance,1> * Element, int Count) Line 158	C++
 	UE4Editor-Niagara.dll!TArray<TSharedRef<FNiagaraEmitterInstance,1>,TSizedDefaultAllocator<32>>::Empty(int Slack) Line 1723	C++
 	UE4Editor-Niagara.dll!FNiagaraSystemInstance::Cleanup() Line 1168	C++
 	UE4Editor-Niagara.dll!FNiagaraSystemInstance::~FNiagaraSystemInstance() Line 1140	C++
 	UE4Editor-Niagara.dll!FNiagaraSystemInstance::`vector deleting destructor'(unsigned int)	C++
 	[Inline Frame] UE4Editor-Niagara.dll!TDefaultDelete<FNiagaraSystemInstance>::operator()(FNiagaraSystemInstance * Ptr) Line 64	C++
 	[Inline Frame] UE4Editor-Niagara.dll!TUniquePtr<FNiagaraSystemInstance,TDefaultDelete<FNiagaraSystemInstance>>::{dtor}() Line 266	C++
 	[Inline Frame] UE4Editor-Niagara.dll!DestructItems(TUniquePtr<FNiagaraSystemInstance,TDefaultDelete<FNiagaraSystemInstance>> * Element, int Count) Line 158	C++
 	UE4Editor-Niagara.dll!TArray<TUniquePtr<FNiagaraSystemInstance,TDefaultDelete<FNiagaraSystemInstance>>,TSizedDefaultAllocator<32>>::Empty(int Slack) Line 1723	C++
 	[Inline Frame] UE4Editor-Niagara.dll!FNiagaraWorldManager::OnBatcherDestroyed_Internal(NiagaraEmitterInstanceBatcher *) Line 391	C++
 	UE4Editor-Niagara.dll!FNiagaraWorldManager::OnBatcherDestroyed(NiagaraEmitterInstanceBatcher * InBatcher) Line 505	C++
 	UE4Editor-Niagara.dll!NiagaraEmitterInstanceBatcher::OnDestroy() Line 1531	C++
 	UE4Editor-Engine.dll!FFXSystemSet::OnDestroy() Line 206	C++
 	UE4Editor-Engine.dll!FFXSystemInterface::Destroy(FFXSystemInterface * FXSystem) Line 69	C++
 	UE4Editor-Engine.dll!UWorld::CleanupWorldInternal(bool bSessionEnded, bool bCleanupResources, UWorld * NewWorld) Line 4541	C++
 	UE4Editor-Engine.dll!UEngine::LoadMap(FWorldContext & WorldContext, FURL URL, UPendingNetGame * Pending, FString & Error) Line 12764	C++
 	UE4Editor-Engine.dll!UEngine::Browse(FWorldContext & WorldContext, FURL URL, FString & Error) Line 12338	C++
 	UE4Editor-Engine.dll!UEngine::TickWorldTravel(FWorldContext & Context, float DeltaSeconds) Line 12536	C++
 	UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1692	C++
 	UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 426	C++
 	UE4Editor.exe!FEngineLoop::Tick() Line 4836	C++
 	[Inline Frame] UE4Editor.exe!EngineTick() Line 62	C++
 	UE4Editor.exe!GuardedMain(const wchar_t * CmdLine) Line 169	C++
 	UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 257	C++

!TArray<TTuple<FNiagaraParameterStore * __ptr64,FNiagaraParameterStoreBinding>,TSizedDefaultAllocator<32> >::RemoveAtSwapImpl()
!FNiagaraParameterStore::UnbindFromSourceStores()
!FNiagaraParameterStore::UnbindAll()
!FNiagaraParameterStore::~FNiagaraParameterStore()
!FNiagaraEmitterInstance::~FNiagaraEmitterInstance()
!TArray<TSharedRef<FNiagaraEmitterInstance,1>,TSizedDefaultAllocator<32> >::Empty()
!FNiagaraSystemInstance::Cleanup()
!FNiagaraSystemInstance::~FNiagaraSystemInstance()
!FNiagaraSystemInstance::`vector deleting destructor'()
!FNiagaraWorldManager::OnWorldCleanup()
!FNiagaraWorldManager::OnWorldCleanup()
!TBaseStaticDelegateInstance<void __cdecl(UWorld * __ptr64,bool,bool),FDefaultDelegateUserPolicy>::ExecuteIfSafe()
!TMulticastDelegate<void __cdecl(UWorld * __ptr64,bool,bool),FDefaultDelegateUserPolicy>::Broadcast()
!UWorld::CleanupWorldInternal()
!FSeamlessTravelHandler::Tick()
!UEngine::TickWorldTravel()
!UGameEngine::Tick()
!FEngineLoop::Tick()
!GuardedMain()
!GuardedMainWrapper()
!WinMain()
!__scrt_common_main_seh() [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-140253 in the post.

0
Login to Vote

Fixed
ComponentUE - Niagara
Affects Versions4.26.2
Target Fix5.0
Fix Commit18781425
Main Commit18781693
Release Commit18781425
CreatedJan 26, 2022
ResolvedJan 29, 2022
UpdatedJan 25, 2023