Crash when CharacterMovementComponent's CapsuleTouched processes overlap with a GeometryCollectionComponent

Summary

When a Character’s CapsuleComponent begins overlapping a Geometry Collection that has generate overlap event on, the engine crashes with an EXCEPTION_ACCESS_VIOLATION. The crash occurs inside UCharacterMovementComponent::CapsuleTouched, which calls GetBoneName() on OtherComp using the overlap’s body index. his code path appears to assume any component with a valid multi-body index (OtherBodyIndex) is a USkinnedMeshComponent, which is true for Skeletal Mesh ragdolls but not for UGeometryCollectionComponent — a different class that also exposes multiple physics bodies per component. The resulting type confusion leads to invalid memory being read and interpreted as a UObject pointer, which crashes inside OutdatedKnownSkinnedAssetDetected() while building a diagnostic string via GetFullName().

What Type of Bug are you experiencing?

Simulation

Steps to Reproduce

  1. Create a new Third Person Template project (Blueprint), default settings, engine version as above.
  2. Add a cube (or any simple mesh) to the level and convert it to a Geometry Collection.
  3. Set collision response with Pawn to Overlap and enable Generate Overlap Events.
  4. Position the Geometry Collection so the default Character will walk directly into it (or drop it near the player start).
  5. Play in Editor (PIE) and walk the Character into the Geometry Collection.

Expected Result

The Character’s capsule overlaps the Geometry Collection normally; OnComponentBeginOverlap fires without error.

Observed Result

The Editor/game crashes immediately on first overlap with: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000012

Affects Versions

5.8

Platform(s)

Windows

For crash reports, include your callstack

UnrealEditor-CoreUObject.dll!UObjectBaseUtility::GetFullName(TStringBuilderBase<wchar_t> & ResultString, const UObject * StopOuter, EObjectFullNameFlags Flags) Ligne 117 C++
UnrealEditor-CoreUObject.dll!UObjectBaseUtility::GetFullName(const UObject * StopOuter, FString & ResultString, EObjectFullNameFlags Flags) Ligne 108 C++
UnrealEditor-CoreUObject.dll!UObjectBaseUtility::GetFullName(const UObject * StopOuter, EObjectFullNameFlags Flags) Ligne 98 C++
UnrealEditor-Engine.dll!USkinnedMeshComponent::OutdatedKnownSkinnedAssetDetected::__l2::<lambda_1>::operator()() Ligne 6050 C++
UnrealEditor-Engine.dll!USkinnedMeshComponent::OutdatedKnownSkinnedAssetDetected() Ligne 6062 C++
UnrealEditor-Engine.dll!USkinnedMeshComponent::GetSkinnedAsset() Ligne 2842 C++
UnrealEditor-Engine.dll!USkinnedMeshComponent::GetBoneName(int BoneIndex) Ligne 2502 C++
UnrealEditor-Engine.dll!UCharacterMovementComponent::CapsuleTouched(UPrimitiveComponent * OverlappedComp, AActor * Other, UPrimitiveComponent * OtherComp, int OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult) Ligne 11694 C++
UnrealEditor-Engine.dll!UCharacterMovementComponent::execCapsuleTouched(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Ligne 454 C++
UnrealEditor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Ligne 7595 C++
UnrealEditor-CoreUObject.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Ligne 2234 C++
[Inline Frame] UnrealEditor-Engine.dll!TScriptDelegate::ProcessDelegate(void *) Ligne 1016 C++
UnrealEditor-Engine.dll!TMulticastScriptDelegate::ProcessDelegate(void * Parameters) Ligne 1441 C++
[Inline Frame] UnrealEditor-Engine.dll!UE::Core::Private::TDelegateFunctionWrapper<void,UPrimitiveComponent *,AActor *,UPrimitiveComponent *,int,bool,FHitResult const &>::CallWrapperImpl(const TDynamicMulticastDelegate<void __cdecl(UPrimitiveComponent *,AActor *,UPrimitiveComponent *,int,bool,FHitResult const &),FNotThreadSafeDelegateMode> &) Ligne 454 C++
[Inline Frame] UnrealEditor-Engine.dll!UE::Core::Private::TDelegateFunctionWrapper<void,UPrimitiveComponent *,AActor *,UPrimitiveComponent *,int,bool,FHitResult const &>::CallWrapper(const TDynamicMulticastDelegate<void __cdecl(UPrimitiveComponent *,AActor *,UPrimitiveComponent *,int,bool,FHitResult const &),FNotThreadSafeDelegateMode> &) Ligne 478 C++
[Inline Frame] UnrealEditor-Engine.dll!TDynamicMulticastDelegate<void cdecl(UPrimitiveComponent *,AActor *,UPrimitiveComponent *,int,bool,FHitResult const &),FNotThreadSafeDelegateMode>::Broadcast(UPrimitiveComponent *) Ligne 1504 C++
UnrealEditor-Engine.dll!TSparseDynamicDelegate<FComponentBeginOverlapSignature_MCSignature,UPrimitiveComponent,FComponentBeginOverlapSignatureInfoGetter>::Broadcast<UPrimitiveComponent *,AActor *,UPrimitiveComponent *,int,bool,FHitResult>(UPrimitiveComponent * <Params_0>, AActor * <Params_1>, UPrimitiveComponent * <Params_2>, int <Params_3>, bool <Params_4>, FHitResult <Params_5>) Ligne 333 C++
UnrealEditor-Engine.dll!UPrimitiveComponent::BeginComponentOverlap(const FOverlapInfo & OtherOverlap, bool bDoNotifies) Ligne 4137 C++
UnrealEditor-Engine.dll!UPrimitiveComponent::UpdateOverlapsImpl(const TArrayView<FOverlapInfo const ,int> * NewPendingOverlaps, bool bDoNotifies, const TArrayView<FOverlapInfo const ,int> * OverlapsAtEndLocation) Ligne 4494 C++
UnrealEditor-Engine.dll!USceneComponent::UpdateOverlaps(const TArrayView<FOverlapInfo const ,int> * PendingOverlaps, bool bDoNotifies, const TArrayView<FOverlapInfo const ,int> * OverlapsAtEndLocation) Ligne 1096 C++
UnrealEditor-Engine.dll!USceneComponent::EndScopedMovementUpdate(FScopedMovementUpdate & CompletedScope) Ligne 1307 C++
UnrealEditor-Engine.dll!FScopedMovementUpdate::~FScopedMovementUpdate() Ligne 79 C++
UnrealEditor-Engine.dll!UCharacterMovementComponent::PerformMovement(float DeltaSeconds) Ligne 3109 C++
UnrealEditor-Engine.dll!UCharacterMovementComponent::ControlledCharacterMove(const UE::Math::TVector & InputVector, float DeltaSeconds) Ligne 6458 C++
UnrealEditor-Engine.dll!UCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) Ligne 1759 C++
[Inline Frame] UnrealEditor-Engine.dll!FActorComponentTickFunction::ExecuteTick::l2::<lambda_1>::operator()(float) Ligne 1701 C++
[Inline Frame] UnrealEditor-Engine.dll!FActorComponentTickFunction::ExecuteTickHelper(UActorComponent *) Ligne 4891 C++
UnrealEditor-Engine.dll!FActorComponentTickFunction::ExecuteTick(float DeltaTime, ELevelTick TickType, ENamedThreads::Type CurrentThread, const TRefCountPtr & MyCompletionGraphEvent) Ligne 1699 C++
[Inline Frame] UnrealEditor-Engine.dll!FTickFunctionTask::DoTask(ENamedThreads::Type CurrentThread, const TRefCountPtr &) Ligne 334 C++
UnrealEditor-Engine.dll!TGraphTask::ExecuteTask() Ligne 703 C++
UnrealEditor-Core.dll!UE::Tasks::Private::FTaskBase::TryExecuteTask() Ligne 524 C++
[Inline Frame] UnrealEditor-Core.dll!FBaseGraphTask::Execute(TArray<FBaseGraphTask *,TSizedDefaultAllocator<32>> &) Ligne 493 C++
UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread(int QueueIndex, bool bAllowStall) Ligne 807 C++
UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksUntilIdle(int QueueIndex) Ligne 707 C++
[Inline Frame] UnrealEditor-Core.dll!FTaskGraphCompatibilityImplementation::ProcessThreadUntilIdle(ENamedThreads::Type) Ligne 1447 C++
UnrealEditor-Core.dll!FTaskGraphCompatibilityImplementation::ProcessUntilTasksComplete(const TArray<TRefCountPtr,TSizedInlineAllocator<4,32,TSizedDefaultAllocator<32>>> & Tasks, ENamedThreads::Type CurrentThreadIfKnown, const TFunction<enum FTaskGraphInterface::EProcessTasksOperation cdecl(int)> & IdleWorkUpdate) Ligne 1620 C++
UnrealEditor-Engine.dll!FTickTaskSequencer::ReleaseTickGroup(ETickingGroup WorldTickGroup, bool bBlockTillComplete, TArray<FTickFunction *,TSizedDefaultAllocator<32>> & TicksToManualDispatch) Ligne 1040 C++
UnrealEditor-Engine.dll!FTickTaskManager::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Ligne 2134 C++
[Inline Frame] UnrealEditor-Engine.dll!UWorld::RunTickGroup(ETickingGroup) Ligne 786 C++
UnrealEditor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Ligne 1750 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Ligne 2171 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Ligne 546 C++
UnrealEditor.exe!FEngineLoop::Tick() Ligne 5859 C++
[Inline Frame] UnrealEditor.exe!EngineTick() Ligne 60 C++
UnrealEditor.exe!GuardedMain(const wchar_t * CmdLine) Ligne 190 C++
UnrealEditor.exe!GuardedMainWrapper(const wchar_t * CmdLine) Ligne 123 C++
UnrealEditor.exe!LaunchWindowsStartup(HINSTANCE
* hInInstance, HINSTANCE
* hPrevInstance, char * formal, int nCmdShow, const wchar_t * CmdLine) Ligne 277 C++
UnrealEditor.exe!WinMain(HINSTANCE
* hInInstance, HINSTANCE
* hPrevInstance, char * pCmdLine, int nCmdShow) Ligne 338 C++
[External Code]

Additional Notes

  • The local variable dump at the crash frame shows this = 0x0000000000000002 for the UObjectBaseUtility pointer passed into GetFullName. This is clearly an invalid address, consistent with a small integer or enum member being read from the wrong byte offset and misinterpreted as a UObject*.
  • We suspect CapsuleTouched’s handling of a valid OtherBodyIndex (indicating a multi-body OtherComp) does not verify that OtherComp is actually a USkinnedMeshComponent before calling bone-resolution functions on it, causing a type-confused read when OtherComp is instead a UGeometryCollectionComponent.
  • This did NOT reproduce with a Static Mesh using identical collision settings (single-body, so this code path is presumably not entered).