Description

A GameplayAbility that destroys its owning actor inside ActivateAbility() causes a crash, because actor destruction will modify the ability list but ActivateAbility() is called within an ABILITYLIST_SCOPE_LOCK().

Besides affecting abilities that explicitly destroy their owning actor, this also may affect other use cases where ActivateAbility() indirectly causes its owner's destruction like when triggering streaming level unloads and map changes.

Edit: won't trigger when ability initiaites a map change or streaming level unload since their executions are deferred until end-of-frame or next frame.

Steps to Reproduce
  • Create an actor BP_MyActor and add an AbilitySystemComponent
  • Create an ability blueprint GA_MyAbility that on ActivateAbility gets the OwningActorFromActorInfo and calls DestroyActor() on it.
  • In BP_MyActor BeginPlay, add a delay node of 0.2 seconds and then call GiveAbilityAndActivateOnce(GA_MyAbility).
  • Observe: a crash with the attached callstack
  • Expected: no crash, the actor should remove successfully and the ability list cleared

Note that the delay is important, as an actor destroying itself during its BeginPlay is handled in a deferred way which avoids the crash.

Callstack

>    UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::ClearAllAbilities() Line 408    C++
     UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::DestroyActiveState() Line 1236    C++
     UnrealEditor-Engine.dll!UActorComponent::ExecuteUnregisterEvents() Line 1756    C++
     UnrealEditor-Engine.dll!UActorComponent::UnregisterComponent() Line 1470    C++
     UnrealEditor-Engine.dll!AActor::UnregisterAllComponents(bool bForReregister) Line 5309    C++
     UnrealEditor-Engine.dll!UWorld::DestroyActor(AActor * ThisActor, bool bNetForce, bool bShouldModifyLevel) Line 1003    C++
     UnrealEditor-Engine.dll!AActor::Destroy(bool bNetForce, bool bShouldModifyLevel) Line 4731    C++
     UnrealEditor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 6686    C++
     UnrealEditor-CoreUObject.dll!UObject::CallFunction(FFrame & Stack, void * const Z_Param__Result, UFunction * Function) Line 1139    C++
     [Inline Frame] UnrealEditor-CoreUObject.dll!FFrame::Step(UObject *) Line 477    C++
     UnrealEditor-CoreUObject.dll!UObject::ProcessContextOpcode(FFrame & Stack, void * const Z_Param__Result, bool bCanFailSilently) Line 3094    C++
     [Inline Frame] UnrealEditor-CoreUObject.dll!FFrame::Step(UObject *) Line 477    C++
     UnrealEditor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1209    C++
     UnrealEditor-CoreUObject.dll!ProcessScriptFunction<void (_cdecl*)(UObject *,FFrame &,void *)>(UObject * Context, UFunction * Function, FFrame & Stack, void * const Z_Param_Result, void[Image Removed](UObject *, FFrame &, void *) ExecFtor) Line 1039    C++
     UnrealEditor-CoreUObject.dll!ProcessLocalFunction(UObject * Context, UFunction * Fn, FFrame & Stack, void * const Z_Param__Result) Line 1279    C++
     [Inline Frame] UnrealEditor-CoreUObject.dll!FFrame::Step(UObject *) Line 477    C++
     UnrealEditor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1209    C++
     UnrealEditor-CoreUObject.dll!UObject::ProcessInternal(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1306    C++
     UnrealEditor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 6686    C++
     UnrealEditor-CoreUObject.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Line 2145    C++
     UnrealEditor-GameplayAbilities.dll!UGameplayAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo * ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData * TriggerEventData) Line 768    C++
     UnrealEditor-GameplayAbilities.dll!UGameplayAbility::CallActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo * ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, TDelegate<void __cdecl(UGameplayAbility *),FDefaultDelegateUserPolicy> * OnGameplayAbilityEndedDelegate, const FGameplayEventData * TriggerEventData) Line 875    C++
     UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::InternalTryActivateAbility(FGameplayAbilitySpecHandle Handle, FPredictionKey InPredictionKey, UGameplayAbility * * OutInstancedAbility, TDelegate<void __cdecl(UGameplayAbility *),FDefaultDelegateUserPolicy> * OnGameplayAbilityEndedDelegate, const FGameplayEventData * TriggerEventData) Line 1702    C++
     UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::GiveAbilityAndActivateOnce(FGameplayAbilitySpec & Spec, const FGameplayEventData * GameplayEventData) Line 336    C++
     UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::K2_GiveAbilityAndActivateOnce(TSubclassOf<UGameplayAbility> AbilityClass, int Level, int InputID) Line 387    C++
     UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::execK2_GiveAbilityAndActivateOnce(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 2054    C++
     UnrealEditor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 6686    C++
     UnrealEditor-CoreUObject.dll!UObject::CallFunction(FFrame & Stack, void * const Z_Param__Result, UFunction * Function) Line 1139    C++
     [Inline Frame] UnrealEditor-CoreUObject.dll!FFrame::Step(UObject *) Line 477    C++
     UnrealEditor-CoreUObject.dll!UObject::ProcessContextOpcode(FFrame & Stack, void * const Z_Param__Result, bool bCanFailSilently) Line 3094    C++
     [Inline Frame] UnrealEditor-CoreUObject.dll!FFrame::Step(UObject *) Line 477    C++
     UnrealEditor-CoreUObject.dll!UObject::execLet(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 2836    C++
     [Inline Frame] UnrealEditor-CoreUObject.dll!FFrame::Step(UObject *) Line 477    C++
     UnrealEditor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1209    C++
     UnrealEditor-CoreUObject.dll!UObject::ProcessInternal(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1306    C++
     UnrealEditor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 6686    C++
     UnrealEditor-CoreUObject.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Line 2145    C++
     UnrealEditor-Engine.dll!AActor::ProcessEvent(UFunction * Function, void * Parameters) Line 1081    C++
     UnrealEditor-Engine.dll!FLatentActionManager::TickLatentActionForObject(float DeltaTime, TMultiMap<int,FPendingLatentAction *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<int,FPendingLatentAction *,1>> & ObjectActionList, UObject * InObject) Line 314    C++
     UnrealEditor-Engine.dll!FLatentActionManager::ProcessLatentActions(UObject * InObject, float DeltaTime) Line 232    C++
     UnrealEditor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1544    C++
     UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1936    C++
     UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 541    C++
     UnrealEditor.exe!FEngineLoop::Tick() Line 5846    C++
     [Inline Frame] UnrealEditor.exe!EngineTick() Line 61    C++
     UnrealEditor.exe!GuardedMain(const wchar_t * CmdLine) Line 188    C++
     UnrealEditor.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 247    C++
     UnrealEditor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 298    C++
     [External Code]    

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-199350 in the post.

0
Login to Vote

Fixed
ComponentUE - Gameplay - Gameplay Ability System
Affects Versions5.25.3
Target Fix5.4
Fix Commit29742026
Main Commit29742034
CreatedOct 31, 2023
ResolvedNov 15, 2023
UpdatedDec 5, 2023