In some occasions, engine code iterates over a certain subsystem type by calling FSubsystemCollection::GetSubsystemArray() and then calling some method on all subsystems of the returned array. This happens, for example, in UWorld::BeginPlay(), which iterates over subsystems of type UWorldSubsystem in an internal SubsystemCollection and calls OnWorldBeginPlay() on each one.
Now, subsystems in general have access to their owner and can call GetSubsystemArray() on it, which forwards the call to the owner's internal SubsystemCollection. If this is done while subsystems are being iterated on (for example, inside a World Subsystem's OnWorldBeginPlay() method), a crash can occur shortly after.
The crash can be explained as follows:
A quick fix was suggested in the related UDN case: code that iterates over subsystems (such as UWorld::BeginPlay()) could make a copy of the subsystem array and iterate on that. Alternatively, FSubsystemCollectionBase::GetSubsystemArrayInternal() could return the array by copy to all of its clients. Another possibility would be to rework the mechanism used by FSubsystemCollectionBase to cache subsystems.
=== Repro Project ===
=== Blank Project ===
[Inline Function] FMallocBinnedCommonBase::FBundle::PushHead(FMallocBinnedCommonBase::FBundleNode* Node) Line 251 C++ [Inline Function] TMallocBinnedCommon<FMallocBinned3,16,128,4,74,131072>::FFreeBlockList::PushToFront(void* InPtr) Line 333 C++ [Inline Function] TMallocBinnedCommon<FMallocBinned3,16,128,4,74,131072>::FPerThreadFreeBlockLists::Free(void* InPtr) Line 473 C++ FMallocBinned3::Realloc(void* Ptr, SIZE_T NewSize, uint32 Alignment) Line 392 C++ FMallocPoisonProxy::Realloc(void* Ptr, SIZE_T NewSize, uint32 Alignment) Line 64 + 0x14 bytes C++ FMemory::Realloc(void* Original, SIZE_T Count, uint32 Alignment) Line 426 + 0x22 bytes C++ TSizedHeapAllocator<32,FMemory>::ForAnyElementType::ResizeAllocation(TSizedHeapAllocator<32,FMemory>::SizeType PreviousNumElements, TSizedHeapAllocator<32,FMemory>::SizeType NumElements, SIZE_T NumBytesPerElement, uint32 AlignmentOfElement) Line 725 + 0xE bytes C++ TArray<TSparseArrayElementOrFreeListLink<TAlignedBytes<32,8u>>,TSizedDefaultAllocator<32>>::ResizeGrow(TArray<TSparseArrayElementOrFreeListLink<TAlignedBytes<32,8u>>,TSizedDefaultAllocator<32>>::SizeType OldNum) Line 3121 C++ [Inline Function] TSparseArray<TSetElement<TTuple<void*,TArray<UStaticMeshComponent*,TSizedDefaultAllocator<32>>>>,TSparseArrayAllocator<TSizedDefaultAllocator<32>,FDefaultBitArrayAllocator>>::AddUninitialized() Line 129 C++ TSet<TTuple<void*,TArray<UStaticMeshComponent*,TSizedDefaultAllocator<32>>>,TDefaultMapHashableKeyFuncs<void*,TArray<UStaticMeshComponent*,TSizedDefaultAllocator<32>>,false>,FDefaultSetAllocator>::Emplace<TKeyInitializer<void*&&>>(TKeyInitializer<void*&&>&& Args, bool* bIsAlreadyInSetPtr) Line 740 C++ [Inline Function] TMapBase<UClass*,TArray<USubsystem*,TSizedDefaultAllocator<32>>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass*,TArray<USubsystem*,TSizedDefaultAllocator<32>>,false>>::Emplace<UClass*const&>(UClass* const& InKey) Line 458 C++ [Inline Function] TMapBase<UClass*,TArray<USubsystem*,TSizedDefaultAllocator<32>>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass*,TArray<USubsystem*,TSizedDefaultAllocator<32>>,false>>::Add(UClass* const& InKey) Line 408 C++ FSubsystemCollectionBase::GetSubsystemArrayInternal(UClass* SubsystemClass) Line 81 C++ UPWGameLoopSubSystem::AddToTick(UObject* _Context, IPWTickableInterface* _Tickable, enum ETickingGroup _TickingGroup) Line 19 C++ UPWGraphSubSystem::OnWorldBeginPlay(UWorld& InWorld) Line 131 C++ UWorld::BeginPlay() Line 5323 + 0xC bytes C++ UEngine::LoadMap(FWorldContext& WorldContext, FURL URL, UPendingNetGame* Pending, FString& Error) Line 15532 C++ UEngine::Browse(FWorldContext& WorldContext, FURL URL, FString& Error) Line 14670 + 0x26 bytes C++ UEngine::TickWorldTravel(FWorldContext& Context, float DeltaSeconds) Line 14868 C++ UGameEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1775 C++ FEngineLoop::Tick() Line 5921 C++
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-221062 in the post.
3 |
Component | UE - Gameplay |
---|---|
Affects Versions | 5.4.3 |
Target Fix | 5.6 |
Created | Aug 6, 2024 |
---|---|
Updated | Sep 30, 2024 |