Smart Objects Crash fix

Hi James,

Sorry for not providing this earlier. The callstack of the crash we were seeing is below - our PR resolves this issue. In this case the this pointer was NULL (an invalid UWorld pointer).

> UnrealEditor-Engine.dll!UWorld::GetTimerManager() Line 7070 C++ UnrealEditor-AIModule.dll!UAITask_MoveTo::ResetTimers() Line 252 C++ UnrealEditor-AIModule.dll!UAITask_MoveTo::OnDestroy(bool bInOwnerFinished) Line 265 C++ UnrealEditor-GameplayBehaviorSmartObjectsModule.dll!UAITask_UseGameplayBehaviorSmartObject::Abort() Line 306 C++ [Inline Frame] UnrealEditor-GameplayBehaviorSmartObjectsModule.dll!Invoke(void(UAITask_UseGameplayBehaviorSmartObject::*)(const FSmartObjectClaimHandle &, ESmartObjectSlotState)) Line 66 C++ [Inline Frame] UnrealEditor-GameplayBehaviorSmartObjectsModule.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(UAITask_UseGameplayBehaviorSmartObject::*)(const FSmartObjectClaimHandle &, ESmartObjectSlotState) &) Line 317 C++ UnrealEditor-GameplayBehaviorSmartObjectsModule.dll!TBaseUObjectMethodDelegateInstance<0,UAITask_UseGameplayBehaviorSmartObject,void __cdecl(FSmartObjectClaimHandle const &,enum ESmartObjectSlotState),FDefaultDelegateUserPolicy>::ExecuteIfSafe(const FSmartObjectClaimHandle & <Params_0>, ESmartObjectSlotState <Params_1>) Line 667 C++ [Inline Frame] UnrealEditor-SmartObjectsModule.dll!TDelegate<void __cdecl(FSmartObjectClaimHandle const &,enum ESmartObjectSlotState),FDefaultDelegateUserPolicy>::ExecuteIfBound(const FSmartObjectClaimHandle & <Params_1>, ESmartObjectSlotState) Line 634 C++ UnrealEditor-SmartObjectsModule.dll!FSmartObjectRuntimeSlot::Release(const FSmartObjectClaimHandle & ClaimHandle, const bool bAborted) Line 169 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectSubsystem::AbortAll(const FSmartObjectHandle Handle, FSmartObjectRuntime & SmartObjectRuntime) Line 640 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectSubsystem::DestroyRuntimeInstanceInternal(const FSmartObjectHandle Handle, FSmartObjectRuntime & SmartObjectRuntime) Line 558 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectSubsystem::RemoveRuntimeInstanceFromSimulation(FSmartObjectRuntime & SmartObjectRuntime, USmartObjectComponent * SmartObjectComponent) Line 544 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectSubsystem::RemoveComponentFromSimulation(USmartObjectComponent & SmartObjectComponent) Line 603 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectSubsystem::UnregisterSmartObjectInternal(USmartObjectComponent & SmartObjectComponent, const bool bDestroyRuntimeState) Line 857 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectSubsystem::UnregisterSmartObject(USmartObjectComponent & SmartObjectComponent) Line 831 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectComponent::UnregisterFromSubsystem(const ESmartObjectUnregistrationType UnregistrationType) Line 228 C++ UnrealEditor-SmartObjectsModule.dll!USmartObjectComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) Line 267 C++ UnrealEditor-Engine.dll!AActor::EndPlay(const EEndPlayReason::Type EndPlayReason) Line 2849 C++ UnrealEditor-Engine.dll!AActor::RouteEndPlay(const EEndPlayReason::Type EndPlayReason) Line 2796 C++ UnrealEditor-Engine.dll!UWorld::RemoveFromWorld(ULevel * Level, bool bAllowIncrementalRemoval, FNetLevelVisibilityTransactionId TransactionId, ULevelStreaming * InOwningLevelStreaming) Line 3659 C++ UnrealEditor-Engine.dll!ULevelStreaming::UpdateStreamingState(bool & bOutUpdateAgain, bool & bOutRedetermineTarget) Line 1095 C++ [Inline Frame] UnrealEditor-Engine.dll!FStreamingLevelPrivateAccessor::UpdateStreamingState(ULevelStreaming *) Line 791 C++ UnrealEditor-Engine.dll!UWorld::UpdateLevelStreaming() Line 4425 C++ UnrealEditor-Engine.dll!UWorld::FlushLevelStreaming(EFlushLevelStreamingType FlushType) Line 4690 C++ UnrealEditor-UnrealEd.dll!UEditorEngine::TeardownPlaySession(FWorldContext & PieWorldContext) Line 814 C++ UnrealEditor-UnrealEd.dll!UEditorEngine::EndPlayMap() Line 344 C++ UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 2473 C++ UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 550 C++ UnrealEditor-LyraEditor-Win64-DebugGame.dll!ULyraEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 39 C++ UnrealEditor-Win64-DebugGame.exe!FEngineLoop::Tick() Line 5877 C++ [Inline Frame] UnrealEditor-Win64-DebugGame.exe!EngineTick() Line 69 C++ UnrealEditor-Win64-DebugGame.exe!GuardedMain(const wchar_t * CmdLine) Line 188 C++ UnrealEditor-Win64-DebugGame.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 266 C++ UnrealEditor-Win64-DebugGame.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 317 C++ [Inline Frame] UnrealEditor-Win64-DebugGame.exe!invoke_main() Line 102 C++ UnrealEditor-Win64-DebugGame.exe!__scrt_common_main_seh() Line 288 C++ kernel32.dll!BaseThreadInitThunk() Unknown ntdll.dll!RtlUserThreadStart() Unknown

I don’t really understand the question around ExternalCancel - we weren’t seeing a crash there, I just wanted to mention that it doesn’t seem to properly clean up it’s child MoveTo task, so it seems like it could potentially leak until the world is destroyed.

Thanks,

Reuben