godotengine / godot

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

"Attempt of waiting to finish on a thread that was never started" error when Godot exits #76456

Closed bend-n closed 1 year ago

bend-n commented 1 year ago

Godot version

e0e93ce09

System information

ArchLinux x11

Issue description

> godot4 --help
...
ERROR: Attempt of waiting to finish on a thread that was never started.
   at: wait_to_finish (core/os/thread.cpp:81)

Actually using the editor also produces this error often.

Steps to reproduce

godot-binary --version

Minimal reproduction project

n/a

qza2468 commented 1 year ago

In Ubuntu22.04, godot4.02, there's no problem. I don't know too much, just give a try : )

bend-n commented 1 year ago

@qza2468

In Ubuntu22.04, godot4.02, there's no problem. I don't know too much, just give a try : )

What version are you on?

akien-mga commented 1 year ago

It's caused by #76345, which exposes invalid usage of the Thread API. The thread shouldn't be waited until it's started.

capnm commented 1 year ago

$ godot -h Here it waits for unnavigable MIDI (driver-thread) ...

  * frame #0: 0x000055555a11d42c godot.linuxbsd.editor.dev.x86_64`Thread::wait_to_finish(this=<unavailable>) at thread.cpp:81:2
    frame #1: 0x00005555577b3ed8 godot.linuxbsd.editor.dev.x86_64`MIDIDriverALSAMidi::close(this=0x00007fffffffd9d0) at midi_driver_alsamidi.cpp:210:9
    frame #2: 0x00005555577b41e3 godot.linuxbsd.editor.dev.x86_64`MIDIDriverALSAMidi::~MIDIDriverALSAMidi(this=<unavailable>) at midi_driver_alsamidi.cpp:250:2
    frame #3: 0x0000555556a341b8 godot.linuxbsd.editor.dev.x86_64`OS_LinuxBSD::~OS_LinuxBSD(this=0x00007fffffffd858) at os_linuxbsd.cpp:1137:1
    frame #4: 0x0000555556a28786 godot.linuxbsd.editor.dev.x86_64`main(argc=<unavailable>, argv=<unavailable>) at godot_linuxbsd.cpp:85:1
    frame #5: 0x00007ffff7c5c083 libc.so.6`__libc_start_main(main=(godot.linuxbsd.editor.dev.x86_64`main at godot_linuxbsd.cpp:43), argc=2, argv=0x00007fffffffdd88, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffdd78) at libc-start.c:308:16
    frame #6: 0x0000555556a2859e godot.linuxbsd.editor.dev.x86_64`_start + 46

At godot app end (4x):

Thread 1 "godot.linuxbsd." hit Breakpoint 1, Thread::wait_to_finish (this=0x7fffffffd918) at core/os/thread.cpp:82
82          print_line("Attempt of waiting to finish on a thread that was never started.");
(gdb) bt
#0  Thread::wait_to_finish (this=0x7fffffffd918) at core/os/thread.cpp:82
#1  0x00005555577a74c4 in AudioDriverALSA::finish (this=0x7fffffffd8d8) at drivers/alsa/audio_driver_alsa.cpp:342
#2  0x0000555559796d79 in AudioServer::finish (this=0x55555ef41520) at servers/audio_server.cpp:1478
#3  0x0000555556addabe in Main::cleanup (p_force=<optimised out>) at main/main.cpp:3432
#4  0x0000555556a28732 in main (argc=<optimised out>, argv=<optimised out>) at platform/linuxbsd/godot_linuxbsd.cpp:75
(gdb) c
Continuing.
Attempt of waiting to finish on a thread that was never started.

Thread 1 "godot.linuxbsd." hit Breakpoint 1, Thread::wait_to_finish (this=0x55555d364110 <AudioDriverManager::dummy_driver+64>) at core/os/thread.cpp:82
82          print_line("Attempt of waiting to finish on a thread that was never started.");
(gdb) bt
#0  Thread::wait_to_finish (this=0x55555d364110 <AudioDriverManager::dummy_driver+64>) at core/os/thread.cpp:82
#1  0x0000555559ccf3cd in AudioDriverDummy::finish (this=0x55555d3640d0 <AudioDriverManager::dummy_driver>) at servers/audio/audio_driver_dummy.cpp:139
#2  0x0000555559796d79 in AudioServer::finish (this=0x55555ef41520) at servers/audio_server.cpp:1478
#3  0x0000555556addabe in Main::cleanup (p_force=<optimised out>) at main/main.cpp:3432
#4  0x0000555556a28732 in main (argc=<optimised out>, argv=<optimised out>) at platform/linuxbsd/godot_linuxbsd.cpp:75
(gdb) c
Continuing.
Attempt of waiting to finish on a thread that was never started.

Thread 1 "godot.linuxbsd." hit Breakpoint 1, Thread::wait_to_finish (this=0x7fffffffd9b8) at core/os/thread.cpp:82
82          print_line("Attempt of waiting to finish on a thread that was never started.");
(gdb) bt
#0  Thread::wait_to_finish (this=0x7fffffffd9b8) at core/os/thread.cpp:82
#1  0x00005555577b3ed8 in MIDIDriverALSAMidi::close (this=0x7fffffffd9b0) at drivers/alsamidi/midi_driver_alsamidi.cpp:210
#2  0x0000555556a2b51c in OS_LinuxBSD::finalize (this=0x7fffffffd838) at platform/linuxbsd/os_linuxbsd.cpp:173
#3  0x0000555556addb23 in Main::cleanup (p_force=<optimised out>) at main/main.cpp:3440
#4  0x0000555556a28732 in main (argc=<optimised out>, argv=<optimised out>) at platform/linuxbsd/godot_linuxbsd.cpp:75
(gdb) c
Continuing.
Attempt of waiting to finish on a thread that was never started.
[Thread 0x7fffdb7fe700 (LWP 110440) exited]
[Thread 0x7fffdbfff700 (LWP 110439) exited]
[Thread 0x7fffe318d700 (LWP 110438) exited]
[Thread 0x7fffe398e700 (LWP 110444) exited]
[Thread 0x7fffe41cf700 (LWP 110436) exited]
[Thread 0x7ffff665c700 (LWP 110433) exited]
[Thread 0x7ffff5e5b700 (LWP 110434) exited]
[Thread 0x7ffff6e5d700 (LWP 110432) exited]

Thread 1 "godot.linuxbsd." hit Breakpoint 1, Thread::wait_to_finish (this=0x7fffffffd9b8) at core/os/thread.cpp:82
82          print_line("Attempt of waiting to finish on a thread that was never started.");
(gdb) bt
#0  Thread::wait_to_finish (this=0x7fffffffd9b8) at core/os/thread.cpp:82
#1  0x00005555577b3ed8 in MIDIDriverALSAMidi::close (this=0x7fffffffd9b0) at drivers/alsamidi/midi_driver_alsamidi.cpp:210
#2  0x00005555577b41e3 in MIDIDriverALSAMidi::~MIDIDriverALSAMidi (this=0x7fffffffd9b8) at drivers/alsamidi/midi_driver_alsamidi.cpp:250
#3  0x0000555556a341b8 in OS_LinuxBSD::~OS_LinuxBSD (this=0x7fffffffd838) at platform/linuxbsd/os_linuxbsd.cpp:1137
#4  0x0000555556a28786 in main (argc=<optimised out>, argv=<optimised out>) at platform/linuxbsd/godot_linuxbsd.cpp:85
(gdb) c
Continuing.
Attempt of waiting to finish on a thread that was never started.
[Inferior 1 (process 110429) exited normally]
akien-mga commented 1 year ago

The fix should be something like this:

diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp
index 81472fe70c..6b35987f70 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.cpp
+++ b/drivers/alsamidi/midi_driver_alsamidi.cpp
@@ -207,7 +207,9 @@ Error MIDIDriverALSAMidi::open() {

 void MIDIDriverALSAMidi::close() {
    exit_thread.set();
-   thread.wait_to_finish();
+   if (thread.is_started()) {
+       thread.wait_to_finish();
+   }

    for (int i = 0; i < connected_inputs.size(); i++) {
        snd_rawmidi_t *midi_in = connected_inputs[i].rawmidi_ptr;

Don't have time to test/check, but it might be that all audio output and MIDI drivers need similar treatment.

capnm commented 1 year ago

I guess also something like this is broken ...

void EditorHelp::cleanup_doc() {
        _wait_for_thread();
        if (doc_gen_use_threads) {
                thread.wait_to_finish();
        }
        memdelete(doc);
}
void EditorHelp::_wait_for_thread() {
    if (thread.is_started()) {
        thread.wait_to_finish();
    }
}

grep doc_gen_use_threads
editor/editor_help.cpp:2242:static bool doc_gen_use_threads = true;
editor/editor_help.cpp:2245:    if (doc_gen_use_threads) {
editor/editor_help.cpp:2258:            if (doc_gen_use_threads) {
editor/editor_help.cpp:2269:            if (doc_gen_use_threads) {

This is as far as I have found durrig work with godot on linux, anyone interested who knows the core code can take a look. capnm-thread_that_was_never_started-patch.zip