Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[C#] Finalizer of AnimationRootNode can trigger #106494

Copy link
Copy link
Open
@lrahmann

Description

@lrahmann
Issue body actions

Tested versions

-Reproducible in [4.3.dev]

System information

Windows C#

Issue description

If a AnimationRootNode isn't manually freed before its collected by garbage collection, the finalizer will call asynchronously into Godot.
This can trigger a race condition if this AnimationRootNode has any AnimationNodes internally which are shared between instances (e.g. using the same resources). And another instance of said AnimationRootNode is instantiated at the same time. While the instantiate will call Object::connect the finalizer will call Object::_disconnect via Object::~Object. Both try to modify the same hash map concurrently, resulting in a crash/corrupted state.

Have not found the time to do a minimal example yet, these are just logged via our bug report tool.
The easiest workaround for now is to always explicitly free these nodes, to prevent the race condition from happening.

Stack Trace Finalizer

Unrailed2!HashMap<Callable,Object::SignalData::Slot,HashableHasher<Callable>,HashMapComparatorDefault<Callable>,DefaultTypedAllocator<HashMapElement<Callable,Object::SignalData::Slot> > >::erase(class Callable * p_key = <Value unavailable error>)+0x122 [D:\godot\core\templates\hash_map.h @ 342] 
Unrailed2!Object::_disconnect(class StringName * p_signal = 0x0000007d`56dff8e8 "changed", class Callable * p_callable = 0x0000007d`56dff8c0, bool p_force = <Value unavailable error>)+0x35b [D:\godot\core\object\object.cpp @ 1483] 
Unrailed2!Object::~Object(void)+0x296 [D:\godot\core\object\object.cpp @ 2106] 
Unrailed2!Resource::~Resource(void)+0x196 [D:\godot\core\io\resource.cpp @ 584] 
Unrailed2!AnimationNodeBlendTree::~AnimationNodeBlendTree(int should_call_delete = 0n0)+0x10 [D:\godot\scene\animation\animation_blend_tree.cpp @ 1829] 
Unrailed2!memdelete(class RefCounted * p_class = 0x00000265`47a995b0)+0x1a [D:\GodotBuild\godot\core\os\memory.h @ 116] 
Unrailed2!godotsharp_internal_refcounted_disposed(class Object * p_ptr = 0x00000265`47a995b0, struct GCHandleIntPtr p_gchandle_to_free = struct GCHandleIntPtr, bool p_is_finalizer = <Value unavailable error>)+0xe2 [D:\GodotBuild\godot\modules\mono\glue\runtime_interop.cpp @ 198] 
UnrailedGodot!GodotSharp_Godot_GodotObject__Dispose_0+0xd9
UnrailedGodot!GodotSharp_Godot_GodotObject__Finalize+0xc
UnrailedGodot!S_P_CoreLib_System_Runtime___Finalizer__DrainQueue+0x28 [/_/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/__Finalizer.cs @ 66] 
UnrailedGodot!S_P_CoreLib_System_Runtime___Finalizer__ProcessFinalizers+0x48 [/_/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/__Finalizer.cs @ 36] 
UnrailedGodot!FinalizerStart(void * pContext = 0x00000000`00000a10)+0x5b [D:\a\_work\1\s\src\coreclr\nativeaot\Runtime\FinalizerHelpers.cpp @ 68] 
kernel32!BaseThreadInitThunk+0x14```

Stack Trace Instantiate

ntdll!KiUserExceptionDispatch+0x2e
Unrailed2!HashMap<Callable,Object::SignalData::Slot,HashableHasher<Callable>,HashMapComparatorDefault<Callable>,DefaultTypedAllocator<HashMapElement<Callable,Object::SignalData::Slot> > >::_insert+0x2b6 [D:\godot\core\templates\hash_map.h @ 225] 
Unrailed2!HashMap<Callable,Object::SignalData::Slot,HashableHasher<Callable>,HashMapComparatorDefault<Callable>,DefaultTypedAllocator<HashMapElement<Callable,Object::SignalData::Slot> > >::operator[]+0x323 [D:\godot\core\templates\hash_map.h @ 546] 
Unrailed2!Object::connect+0x6b9 [D:\godot\core\object\object.cpp @ 1426] 
Unrailed2!AnimationNodeBlendTree::add_node+0x5c9 [D:\godot\scene\animation\animation_blend_tree.cpp @ 1435] 
Unrailed2!AnimationNodeBlendTree::_set+0x191 [D:\godot\scene\animation\animation_blend_tree.cpp @ 1663] 
Unrailed2!Object::set+0x239 [D:\godot\core\object\object.cpp @ 296] 
Unrailed2!Resource::duplicate_for_local_scene+0x1eb [D:\godot\core\io\resource.cpp @ 300] 
Unrailed2!SceneState::make_local_resource+0x320 [D:\godot\scene\resources\packed_scene.cpp @ 628] 
Unrailed2!SceneState::instantiate+0x1885 [D:\godot\scene\resources\packed_scene.cpp @ 369] 
Unrailed2!PackedScene::instantiate+0x6b [D:\godot\scene\resources\packed_scene.cpp @ 2094] 
Unrailed2!call_with_ptr_args_ret_helper+0xb [D:\godot\core\variant\binder_common.h @ 335] 
Unrailed2!call_with_ptr_args_ret+0xb [D:\godot\core\variant\binder_common.h @ 583] 
Unrailed2!MethodBindTR<RenderingServer,unsigned long long,RenderingServer::RenderingInfo>::ptrcall+0x19 [D:\godot\core\object\method_bind.h @ 545] 
UnrailedGodot!GodotSharp_Godot_NativeCalls__godot_icall_1_302+0x9f
UnrailedGodot!GodotSharp_Godot_PackedScene__Instantiate_0+0x35
UnrailedGodot!UnrailedGodot_UnrailedGodot_GodotGraphics__CreateStatefulModel+0x72 [E:\Dev\Mono\Code\FrontendGodot\Src\Engine\GodotGraphics.cs @ 1053] 
UnrailedGodot!UnrailedGodot_common_UI_Drawer_PlayerImageDrawer__DrawPlayer+0x1f6 [E:\Dev\Mono\Code\Source\Common\Unrailed2\UI\Drawer\PlayerImageDrawer.cs @ 315] 
UnrailedGodot!UnrailedGodot_common_UI_Drawer_PlayerImageDrawer__DoDraw+0x55 [E:\Dev\Mono\Code\Source\Common\Unrailed2\UI\Drawer\PlayerImageDrawer.cs @ 167] 
UnrailedGodot!UnrailedGodot_common_UI_GameStaticContext__Draw+0x39 [E:\Dev\Mono\Code\Source\Common\UI\FullscreenUIDrawerWithState.cs @ 386] 
UnrailedGodot!UnrailedGodot_common_Renderer_RenderWorld__Draw+0x85 [E:\Dev\Mono\Code\Source\Common\Renderer\IRenderWorld.cs @ 244] 
UnrailedGodot!UnrailedGodot_common_Screens_ScreenManager__Draw+0xa1 [E:\Dev\Mono\Code\Source\Common\Screens\ScreenManager.cs @ 321] 
UnrailedGodot!UnrailedGodot_common_Unrailed2_GameManager__Draw+0x40 [E:\Dev\Mono\Code\Source\Common\Unrailed2\GameManager.cs @ 136] 
UnrailedGodot!UnrailedGodot_UnrailedGodot_MainGame___Process+0x274 [E:\Dev\Mono\Code\FrontendGodot\Src\Engine\MainGame.cs @ 441] 
UnrailedGodot!GodotSharp_Godot_MainLoop__InvokeGodotClassMethod+0x2b7
UnrailedGodot!UnrailedGodot_UnrailedGodot_MainGame__InvokeGodotClassMethod+0x332 [E:\Dev\Mono\Code\FrontendGodot\.godot\mono\temp\obj\ExportRelease\win-x64\Godot.SourceGenerators\Godot.SourceGenerators.ScriptMethodsGenerator\UnrailedGodot.MainGame_ScriptMethods.generated.cs @ 160] 
UnrailedGodot!GodotSharp_Godot_Bridge_CSharpInstanceBridge__Call+0xae
Unrailed2!CSharpInstance::callp+0x42 [D:\GodotBuild\godot\modules\mono\csharp_script.cpp @ 1650] 
Unrailed2!MainLoop::_gdvirtual__process_call+0x5b [D:\godot\core\os\main_loop.h @ 46] 
Unrailed2!MainLoop::process+0x84 [D:\godot\core\os\main_loop.cpp @ 67] 
Unrailed2!SceneTree::process+0x17 [D:\godot\scene\main\scene_tree.cpp @ 507] 
Unrailed2!Main::iteration+0x430 [D:\godot\main\main.cpp @ 4152] 
Unrailed2!OS_Windows::run+0x35 [D:\godot\platform\windows\os_windows.cpp @ 1658] 
Unrailed2!widechar_main+0x1d0 [D:\godot\platform\windows\godot_windows.cpp @ 184] 
Unrailed2!_main+0x3d [D:\godot\platform\windows\godot_windows.cpp @ 206] 
Unrailed2!main+0xf [D:\godot\platform\windows\godot_windows.cpp @ 227] 
Unrailed2!invoke_main+0x22 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 
Unrailed2!__scrt_common_main_seh+0x10c [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 
kernel32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21

Steps to reproduce

TODO.

Minimal reproduction project (MRP)

TODO.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.