Not a Regression.
Tested in:
//UE5/Release-5.0 CL 18747223 Source-GitHub
//UE4/Release-4.27 CL 18319896 Binary
User Description:
"The crash test code is located at Source/HashBucketLockedBug/Private/Bug.cpp, every step in the code contain technical explanation.
After creating many objects while iterating an outer, the hash bucket of the outer is read-locked permanently, causing the ReadOnlyLock check to fail inside FHashBucket::Add, with the following fatal error:
Fatal error: [Link Removed] [Line: 104]
Trying to add TestObject /Game/TestPackage.TestPackage:LotOfObjectsInside.CrashingObject to a hash bucket that is currently being iterated over which is not allowed and may lead to undefined behavior!
Note that the object / hash bucket is not being iterated at the time of the creation of the object.
The crash must be caused because ThreadHash.ObjectOuterMap is rebuilt while iterating: the Inners variable in ForEachObjectWithOuter point to a memory location that was previously freed (the outer map is rehashed while iterating)."
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "ActorBug.generated.h" UCLASS() class UTestObject : public UObject { GENERATED_BODY() }; UCLASS() class UObjBug : public UObject { GENERATED_BODY() public: UObjBug(); UPROPERTY() UTestObject* TestObj1; UPROPERTY() UTestObject* TestObj2; }; UCLASS() class LQA00404557_API AActorBug : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AActorBug(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; private: UPROPERTY() UObjBug* TestParentObject; };
4. In the ActorBug.cpp delete everything then paste in the following code:
// Fill out your copyright notice in the Description page of Project Settings. #include "ActorBug.h" UObjBug::UObjBug() : TestObj1(nullptr) , TestObj2(nullptr) { } // Sets default values AActorBug::AActorBug() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; TestParentObject = nullptr; } // Called when the game starts or when spawned void AActorBug::BeginPlay() { Super::BeginPlay(); UPackage* const Pkg = CreatePackage(TEXT("/Game/TestPackage")); TestParentObject = NewObject<UObjBug>(Pkg, "TestPackage", RF_Public | RF_Standalone); // Create an object that will contain at least 1 object (so there is something to iterate). TestParentObject->TestObj1 = NewObject<UTestObject>(TestParentObject, "FailingOuter"); UTestObject* const NewObj = NewObject<UTestObject>(TestParentObject->TestObj1, "TestObject"); // Create another object where many objects will be created in it. TestParentObject->TestObj2 = NewObject<UTestObject>(TestParentObject, "NewObjects"); // Iterate TestObj1 and create many objects containing a children in TestObj2. // This will cause ThreadHash.ObjectOuterMap to be rehashed (when it reaches HashSize, so 4096). // Elements in ObjectOuterMap will then be reallocated, causing Inners in ForEachObjectWithOuter to be invalid, // leading to undefined behavior (the hash bucked will not be able to be unlocked). ForEachObjectWithOuter(TestParentObject->TestObj1, [this](UObject* Obj) { for (SIZE_T Idx = 1; Idx <= 5000; Idx++) { UTestObject* const NewObj = NewObject<UTestObject>(TestParentObject->TestObj2, FName("DupObj", Idx)); NewObject<UTestObject>(NewObj, "Children"); } }, false); // Now create an object inside TestObj1: it will try to add the new object in the TestObj1 outer, // but the associated hash bucket of TestObj1 is permanently locked because of the bug above, // causing a failure when adding the new object to the hash bucket. NewObject<UTestObject>(TestParentObject->TestObj1, "CrashingObject"); } // Called every frame void AActorBug::Tick(float DeltaTime) { Super::Tick(DeltaTime); }
5. Save in Visual Studio then Compile in Editor using the "Recompiles and Reloads C++" button in the lower right corner of the editor.
6. Drag and drop the ActorBug into the level then Play in Editor
Expected Results:
All of objects should be created without causing issues to the outer being iterated.
Actual Results:
Editor Crashes with a Fatal Error in UObjectHash.cpp Line 319
[2022.02.08-19.53.45:495][452]LogWindows: Error: === Critical error: === [2022.02.08-19.53.45:495][452]LogWindows: Error: [2022.02.08-19.53.45:495][452]LogWindows: Error: Fatal error: [File:E:\Git\UE5Rel-18747223\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectHash.cpp] [Line: 319] [2022.02.08-19.53.45:495][452]LogWindows: Error: Trying to modify UObject map (FindOrAdd) that is currently being iterated. Please make sure you're not creating new UObjects or Garbage Collecting while iterating UObject hash tables. [2022.02.08-19.53.45:495][452]LogWindows: Error: [2022.02.08-19.53.45:495][452]LogWindows: Error: [2022.02.08-19.53.45:495][452]LogWindows: Error: [2022.02.08-19.53.45:495][452]LogWindows: Error: [2022.02.08-19.53.45:495][452]LogWindows: Error: [2022.02.08-19.53.45:505][452]LogExit: Executing Sta
I am not able to find world outliner how to enable it?
Undefined sysmbol: typeinfo for AActor when cross-compile linux dedicated server on windows
How to achieve HLSL Multiple Render Target in Material blueprints?
How can i modify the param name in EQS node
When I open UE4 4.24.3 it appears that. Does anyone know how to solve?
Teleporter in the Creative Hub is Locked and cannot be accessed
Delay nodes occasionally don't fire the "Completed" output in a nativized build
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-141815 in the post.
0 |
Component | UE - Foundation |
---|---|
Affects Versions | 5.0 |
Target Fix | 5.0 |
Created | Feb 8, 2022 |
---|---|
Resolved | Feb 21, 2022 |
Updated | Feb 22, 2022 |