Crash in UObjectArray during level load

Hi All,
We hit an odd crash during the async loading code. Callstack is below.

Main points:

  1. StaticAllocateObject is being called in the Async loading thread.

  2. It enters the following if statement (ln 2447)
    if (!bCreatingCDO && (!bCanRecycleSubobjects || !Obj->IsDefaultSubobject()))

  3. It enters Obj->~UObject();

  4. This ends up calling FUObjectArray::FreeUObjectIndex

  5. 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