Hi All,
We hit an odd crash during the async loading code. Callstack is below.
Main points:
-
StaticAllocateObject is being called in the Async loading thread.
-
It enters the following if statement (ln 2447)
if (!bCreatingCDO && (!bCanRecycleSubobjects || !Obj->IsDefaultSubobject())) -
It enters Obj->~UObject();
-
This ends up calling FUObjectArray::FreeUObjectIndex
-
It hits the check statement at the top due to it not being a game or GC thread.
The object in our crash was a UMoviePlayer inside of a UActorSequence.
Callstack:
ReportAssert(const wchar_t * ErrorMessage, int NumStackFramesToIgnore) Line 1627 C++
FWindowsErrorOutputDevice::Serialize(const wchar_t * Msg, ELogVerbosity::Type Verbosity, const FName & Category) Line 79 C++
FOutputDevice::LogfImpl(const wchar_t * Fmt, ...) Line 61 C++
AssertFailedImplV(const char * Expr, const char * File, int Line, const wchar_t * Format, char * Args) Line 104 C++
FDebug::CheckVerifyFailedImpl(const char * Expr, const char * File, int Line, const wchar_t * Format, ...) Line 461 C++
FUObjectArray::FreeUObjectIndex(UObjectBase * Object) Line 282 C++
UObjectBase::~UObjectBase() Line 131 C++
StaticAllocateObject(const UClass * InClass, UObject * InOuter, FName InName, EObjectFlags InFlags, EInternalObjectFlags InternalSetFlags, bool bCanRecycleSubobjects, bool * bOutRecycledSubobject, UPackage * ExternalPackage) Line 2482 C++
StaticConstructObject_Internal(const FStaticConstructObjectParameters & Params) Line 3190 C++
FObjectInstancingGraph::GetInstancedSubobject(UObject * SourceSubobject, UObject * CurrentValue, UObject * CurrentObject, bool bDoNotCreateNewInstance, bool bAllowSelfReference) Line 228 C++
FObjectInstancingGraph::InstancePropertyValue(UObject * ComponentTemplate, UObject * CurrentValue, UObject * Owner, bool bIsTransient, bool bCausesInstancing, bool bAllowSelfReference) Line 299 C++
FObjectPropertyBase::InstanceSubobjects(void * Data, const void * DefaultData, UObject * InOwner, FObjectInstancingGraph * InstanceGraph) Line 52 C++
UStruct::InstanceSubobjectTemplates(void * Data, const void * DefaultData, UStruct * DefaultStruct, UObject * Owner, FObjectInstancingGraph * InstanceGraph) Line 2155 C++
FObjectInitializer::InstanceSubobjects(UClass * Class, bool bNeedInstancing, bool bNeedSubobjectInstancing) Line 2937 C++
FObjectInitializer::PostConstructInit() Line 2851 C++
FObjectInitializer::~FObjectInitializer() Line 2705 C++
StaticConstructObject_Internal(const FStaticConstructObjectParameters & Params) Line 3196 C++
I’ve modified the check to allow for this to happen on the async loading thread, as this seems to be expected under certain circumstances.
// ILLFONIC CHANGE BEGIN - chance.lyon - Allow this to happen in the async loading thread. This can get called from UOBjectGlobals ln 2481: Obj->~UObject();
//check(IsInGameThread() || IsInGarbageCollectorThread() );
check(IsInGameThread() || IsInGarbageCollectorThread() || IsInAsyncLoadingThread());
// ILLFONIC CHANGE END
Is this workaround correct? Or is this crash indicative of a deeper issue?
Thanks,
- Chance