godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.26k stars 21.22k forks source link

Godot crashes due to `Animation` is null pointer. #80715

Open RechieKho opened 1 year ago

RechieKho commented 1 year ago

Godot version

Godot Engine v4.2.dev.custom_build (c5a7462a00a665a72c7c1a746c105e3c1c475c96)

System information

Arch Linux, AMD ATI Radeon Vega Series / Radeon Vega Mobile Series, CPU: AMD Ryzen 3 3200G (4) @ 3.600GHz

Issue description

Somehow in scene/animation/animation_player.cpp:1013, cd.from->animation is a null pointer when there is an AnimationPlayer in a child scene like given minimal reproduction project.

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.2.dev.custom_build (c5a7462a00a665a72c7c1a746c105e3c1c475c96)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /usr/lib/libc.so.6(+0x3e710) [0x7f774ec3e710] (??:0)
[2] Animation::get_length() const (/home/rechie/Documents/cxx_projects/gobread/scene/resources/animation.cpp:3711)
[3] AnimationPlayer::_animation_process_data(AnimationPlayer::PlaybackData&, double, float, bool, bool) (/home/rechie/Documents/cxx_projects/gobread/scene/animation/animation_player.cpp:1013)
[4] AnimationPlayer::_animation_process2(double, bool) (/home/rechie/Documents/cxx_projects/gobread/scene/animation/animation_player.cpp:1110)
[5] AnimationPlayer::_animation_process(double) (/home/rechie/Documents/cxx_projects/gobread/scene/animation/animation_player.cpp:1281)
[6] AnimationPlayer::_notification(int) (/home/rechie/Documents/cxx_projects/gobread/scene/animation/animation_player.cpp:250)
[7] AnimationPlayer::_notificationv(int, bool) (/home/rechie/Documents/cxx_projects/gobread/scene/animation/animation_player.h:66)
[8] Object::notification(int, bool) (/home/rechie/Documents/cxx_projects/gobread/core/object/object.cpp:798)
[9] SceneTree::_process_group(SceneTree::ProcessGroup*, bool) (/home/rechie/Documents/cxx_projects/gobread/scene/main/scene_tree.cpp:947)
[10] SceneTree::_process(bool) (/home/rechie/Documents/cxx_projects/gobread/scene/main/scene_tree.cpp:1027)
[11] SceneTree::process(double) (/home/rechie/Documents/cxx_projects/gobread/scene/main/scene_tree.cpp:508)
[12] Main::iteration() (/home/rechie/Documents/cxx_projects/gobread/main/main.cpp:3467)
[13] OS_LinuxBSD::run() (/home/rechie/Documents/cxx_projects/gobread/platform/linuxbsd/os_linuxbsd.cpp:933)
[14] /home/rechie/Documents/cxx_projects/gobread/bin/godot.linuxbsd.editor.dev.x86_64.llvm(main+0x1d3) [0x564c2b4e9663] (/home/rechie/Documents/cxx_projects/gobread/platform/linuxbsd/godot_linuxbsd.cpp:76)
[15] /usr/lib/libc.so.6(+0x27cd0) [0x7f774ec27cd0] (??:0)
[16] /usr/lib/libc.so.6(__libc_start_main+0x8a) [0x7f774ec27d8a] (??:0)
[17] /home/rechie/Documents/cxx_projects/gobread/bin/godot.linuxbsd.editor.dev.x86_64.llvm(_start+0x25) [0x564c2b4e93b5] (??:?)
-- END OF BACKTRACE --
================================================================

I have tried adding

ERR_FAIL_COND(cd.from->animation == nullptr); // Line 1012

And it screams

...
ERROR: Condition "cd.from->animation == nullptr" is true.
   at: _animation_process_data (scene/animation/animation_player.cpp:1013)
ERROR: Condition "cd.from->animation == nullptr" is true.
   at: _animation_process_data (scene/animation/animation_player.cpp:1013)
ERROR: Condition "cd.from->animation == nullptr" is true.
   at: _animation_process_data (scene/animation/animation_player.cpp:1013)
ERROR: Condition "cd.from->animation == nullptr" is true.
   at: _animation_process_data (scene/animation/animation_player.cpp:1013)
ERROR: Condition "cd.from->animation == nullptr" is true.
   at: _animation_process_data (scene/animation/animation_player.cpp:1013)

Steps to reproduce

Open minimal reproduction project in Godot editor.

Minimal reproduction project

godot_crash.zip

RechieKho commented 1 year ago

The crash need that:

The evil scene must be the first tab
The evil child scene must being edited.
The child scene must not be editable
RechieKho commented 1 year ago

I try to play something in READY in _notification. And I scatter prints all over the code when there are changes to animation_set and playback.current.from.

 cache inserting animation, if it is true, we are dead:  RESET false
 cache inserting animation, if it is true, we are dead:  idle false
play:  false AnimationPlayer
AnimationPlayer process:  false
AnimationPlayer process2:  false
First process
play:  false AnimationPlayer
AnimationPlayer To be erased:  idle
AnimationPlayer cache inserting animation, if it is true, we are dead:  idle false
 cache inserting animation, if it is true, we are dead:  RESET false
 cache inserting animation, if it is true, we are dead:  idle false
play:  false AnimationPlayer
AnimationPlayer process:  false
AnimationPlayer process2:  false
First process
play:  false AnimationPlayer
AnimationPlayer process:  true
AnimationPlayer process2:  true
ERROR: Condition "cd.from->animation == nullptr" is true.
   at: _animation_process_data (scene/animation/animation_player.cpp:1014)
AnimationPlayer process:  true
AnimationPlayer process2:  true
ERROR: Condition "cd.from->animation == nullptr" is true.

Anything before First process is called in READY. The first First process is caused by the child scene while the next one is the evil scene. Everything is OK in READY but not in INTERAL_PROCESS, Don't know what happen that playback.current.from->animation become nullptr before internal process after ready

RechieKho commented 1 year ago

By the way, in the child scene, a ready signal is connected to AnimationPlayer.play so it plays on ready. Not sure whether is it normal for the editor to play animation on ready.

AThousandShips commented 1 year ago

Please update your comments instead of making many comments after one another, each will ping people who subscribe to the repository

KurtBliss commented 1 year ago

I wonder why the animation player auto plays in the editor for the MRP. I can't get that to happen on a separate project unless I use a tool script but the MRP doesn't use one... For the MRP I tried deleting the .godot folder still does it...

KurtBliss commented 1 year ago

I found one solution by adding the following code at the beginning of AnimationPlayer::_animation_process_data. Or higher if preferable in the call stack.

if (cd.from->animation == nullptr) {
    playback.current.from = &animation_set[playback.assigned];
}

I'm not entirely sure of the cause of this issue. But the native object signals being emitted and playing the animation while it's already playing in another scene tab.

This issue is similar / related to PR #74796 and proposal #4850.

KurtBliss commented 1 year ago

So after some updates this specific crash doesn't happen, but the following crash now occurs though. Not sure how to fix this one. Not sure exactly which commit exactly, but a lot changes has been made to the animation player recently.

Exception thrown at 0x00007FF7D908A62C in godot.windows.editor.x86_64.exe: 0xC0000005: Access violation reading location 0x0000000000000060. 
>   godot.windows.editor.x86_64.exe!AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath,int,HashMapHasherDefault,HashMapComparatorDefault<NodePath>,DefaultTypedAllocator<HashMapElement<NodePath,int>>> & p_track_map) Line 292  C++
    godot.windows.editor.x86_64.exe!AnimationMixer::_process_animation(double p_delta, bool p_update_only) Line 920 C++
    godot.windows.editor.x86_64.exe!AnimationMixer::_notification(int p_what) Line 2014 C++
    [Inline Frame] godot.windows.editor.x86_64.exe!AnimationMixer::_notificationv(int) Line 46  C++
    godot.windows.editor.x86_64.exe!AnimationPlayer::_notificationv(int p_notification, bool p_reversed) Line 39    C++
    godot.windows.editor.x86_64.exe!Object::notification(int p_notification, bool p_reversed) Line 831  C++
    godot.windows.editor.x86_64.exe!SceneTree::_process_group(SceneTree::ProcessGroup * p_group, bool p_physics) Line 950   C++
    godot.windows.editor.x86_64.exe!SceneTree::_process(bool p_physics) Line 1023   C++
    godot.windows.editor.x86_64.exe!SceneTree::process(double p_time) Line 510  C++
    godot.windows.editor.x86_64.exe!Main::iteration() Line 3573 C++
    godot.windows.editor.x86_64.exe!OS_Windows::run() Line 1474 C++
    godot.windows.editor.x86_64.exe!widechar_main(int argc, wchar_t * * argv) Line 182  C++
    godot.windows.editor.x86_64.exe!_main() Line 206    C++
    godot.windows.editor.x86_64.exe!main(int argc, char * * argv) Line 218  C++
    [External Code] 

Edit: Godot Version: v4.2.dev.custom_build [a2f90d565]

akien-mga commented 1 year ago

CC @TokageItLab

TokageItLab commented 1 year ago

As far as I can see from the stack traces, even after the implementation of AnimationMixer, the main cause of this problem is the same as before.

The cause is probably either that AnimationPlayer(Mixer) is trying to play the animation before the animation list is generated, or that AnimationPlayer(Mixer) is updated immediately after playback and the animation list is lost, but I don't know what is causing it. The signal is suspicious, but I'm not sure since it crashed even when I make it connect with deferred option.

What I would like you to do for investigating is to create a more minimal project which can reproduce this bug with fewer nodes and minimal signal connections, since current MRP is still large.

KurtBliss commented 1 year ago

Here's a smaller MRP, GodotDevAnimCrash.zip.

To reproduce crash:

  1. Open main.tscn
  2. Open child_animation.tscn
  3. Return to main tab
starryalley commented 11 months ago

I probably hit the same crash (same call stack) today by gdscript modifying the AnimationLibrary added to the AnimationPlayer node while the AnimationPlayer is playing. I am on 4.1.3 stable.

In the end I have to always call AnimationPlayer.stop() before making any changes to the Animation or AnimationLibrary associated with that AnimationPlayer.

jinyangcruise commented 6 months ago

To those who use AnimationPlayer.play in _ready() which using a @tool label, there is a workaround to avoid engine crash:

add some wait time before playing animation, like:

@tool

@onready var animation_player: AnimationPlayer = $AnimationPlayer

func _ready():
    await get_tree().process_frame # add this line
    animation_player.play(animation_name)
KoBeWi commented 3 months ago

I checked the minimal project. It has ready signal connected to AnimationPlayer's play(), so the animation autoplays when scene is opened. For whatever reason this causes crash when scene is changed, even if you stop the animation. Disconnecting the signal fixes the crash. When play the animation from the Animation editor it doesn't crash.

Better stack trace:

CrashHandlerException: Program crashed
Engine version: Godot Engine v4.3.rc.custom_build (e343dbbcc1030f04dc5833f1c19d267a17332ca9)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[0] Object::get_instance_id (C:\godot_source\core\object\object.h:801)
[1] AnimationPlayer::_blend_pre_process (C:\godot_source\scene\animation\animation_player.cpp:299)
[2] AnimationMixer::_process_animation (C:\godot_source\scene\animation\animation_mixer.cpp:939)
[3] AnimationMixer::_notification (C:\godot_source\scene\animation\animation_mixer.cpp:2210)
[4] AnimationMixer::_notificationv (C:\godot_source\scene\animation\animation_mixer.h:43)
[5] AnimationPlayer::_notificationv (C:\godot_source\scene\animation\animation_player.h:39)
[6] Object::notification (C:\godot_source\core\object\object.cpp:873)
[7] SceneTree::_process_group (C:\godot_source\scene\main\scene_tree.cpp:961)
[8] SceneTree::_process (C:\godot_source\scene\main\scene_tree.cpp:1042)
[9] SceneTree::process (C:\godot_source\scene\main\scene_tree.cpp:528)
[10] Main::iteration (C:\godot_source\main\main.cpp:4106)
[11] OS_Windows::run (C:\godot_source\platform\windows\os_windows.cpp:1666)
[12] widechar_main (C:\godot_source\platform\windows\godot_windows.cpp:181)
[13] _main (C:\godot_source\platform\windows\godot_windows.cpp:206)
[14] main (C:\godot_source\platform\windows\godot_windows.cpp:220)
[15] WinMain (C:\godot_source\platform\windows\godot_windows.cpp:234)
[16] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
[17] <couldn't map PC to fn name>
-- END OF BACKTRACE --