Dangling pointer crash in UObject::DestroyNonNativeProperties()

Sequence of potentially relevant events leading up to crash:

Sequence after starting cook:

[2025.05.27-18.46.45:039] 1. New UObject Default__SKEL_BP_Derived_C (address 0000023974537000) created with BP class named SKEL_BP_Derived_C (address 0000023BCC633F00)

[2025.05.27-18.46.46:365] 2. PurgeClass called on SKEL_BP_Derived_C (address 0000023BCC633F00)

[2025.05.27-18.46.46:367] 3. Another new UObject created with same name/class as #2

[2025.05.27-18.46.46:422] 4. PurgeClass called again on SKEL_BP_Derived_C (address 0000023BCC633F00)

[2025.05.27-18.46.46:424] 5. Several more new UObjects created with same name/class as #2

[2025.05.27-18.50.01:161] 6. Periodic GC starts via CookCommandlet

[2025.05.27-18.50.06:792] 7. BeginDestroy called on SKEL_BP_Derived_C (address 0000023BCC633F00)

[2025.05.27-18.50.06:804] 8. BeginDestroy called on REINST_SKEL_BP_Derived_C (address 0000023BCCFABD00)

[2025.05.27-18.51.57:883] 9. FinishDestroy called on SKEL_BP_Derived_C (0000023BCC633F00)

[2025.05.27-18.51.57:883] 10. DestroyNonNativeProperties called on UObject SKEL_BP_Derived_C (address 0000023BCC633F00) with class BlueprintGeneratedClass (address 00007FF460FA9258)

[2025.05.27-18.51.57:885] 11. DestroyNonNativeProperties called on UObject Default__SKEL_BP_Derived_C (address 0000023974537000) with class REINST_SKEL_BP_Derived_C (address 0000023BCCFABD00)

#11 Crashes with a read access violation while iterating the DestructorLink properties on this line:

P->DestroyValue_InContainer(this);

A couple interesting notes:

  • The class of the UObject has changed from SKEL_BP_Derived_C -> REINST_SKEL_BP_Derived_C. Presumably this is part of the BP compilation process?
  • REINST_SKEL_BP_Derived_C has had BeginDestroy called, but not FinishDestroy yet.
  • SKEL_BP_Derived_C has had FinishDestroy called.
  • P non-null but likely dangling pointer.

Some additional info:

I’ve found that the deletion of the FProperties in question is happening via a call to DestroyPropertiesPendingDestruction() on a class named SKEL_BP_Base_C, where BP_Base is the parent Blueprint of BP_Derived. In terms of sequencing, this happens between steps 8 and 9 above.

It looks like a very similar issue was reported a few years ago by Malte Thiesen about 1/2 way down this thread, though I don’t see a resolution:

[Content removed]

I think it boils down to this - Is there a mechanism that enforces that a child class should be deleted before it’s SuperStruct, assuming they’ve both been marked for GC? It looks like this might do it in UStruct::AddReferencedObjects:

Collector.AddReferencedObject( This->SuperStruct.GetAccessTrackedObjectPtr(), This );

Hi there, can you provide more context:

  • Is this a crash that you’ve encountered once or multiple times, and can you reproduce this at will?
  • What are the steps you’re taking in editor that cause this crash, or what code are you executing?

Hi, this happens when running a cook in our CI or locally from cmd line. It is 100% repro with our project.

Hi Chris,

Is this something that you would be able to repro in a small project for us to look at?

Thanks,

Dave

I pair debugged this with Chris, and it comes down to a stale pointer caused by a failure case involving Skeleton class regeneration. Working on a test case to exercise the code but we need a:

CurClass->Bind(); CurClass->StaticLink(true);

in FBlueprintCompileReinstancer::MoveDependentSkelToReinst’s handling of REINST/Garbage classes.