Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freeing AudioStreamPlayer cause crash due using it in different thread #54099

Open
Tracked by #76797
qarmin opened this issue Oct 21, 2021 · 1 comment
Open
Tracked by #76797

Freeing AudioStreamPlayer cause crash due using it in different thread #54099

qarmin opened this issue Oct 21, 2021 · 1 comment

Comments

@qarmin
Copy link
Contributor

qarmin commented Oct 21, 2021

Godot version

3.4.beta.custom_build. 01ae488

System information

Ubuntu 21.10 - Nvidia GTX 970, Gnome shell 3.38 X11

Issue description

When executing

func _process(delta) -> void:
	for i in range(40):
		var rr = AudioStreamPlayer.new()
		rr.notification(10, false)
		rr.queue_free()

Godot crashes with this backtrace

=================================================================
==70545==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000e2e90 at pc 0x00000f569486 bp 0x7f4d04775480 sp 0x7f4d04775470
READ of size 8 at 0x6160000e2e90 thread T3
ERROR: Condition "!get_viewport()" is true.
   at: _notification (scene/main/node.cpp:68)
    #0 0xf569485 in AudioStreamPlayer::_mix_audios(void*) scene/audio/audio_stream_player.h:72
    #1 0x10817296 in AudioServer::_mix_step() servers/audio_server.cpp:337
    #2 0x10814485 in AudioServer::_driver_process(int, int*) servers/audio_server.cpp:252
    #3 0x1080dd70 in AudioDriver::audio_server_process(int, int*, bool) servers/audio_server.cpp:62
    #4 0x8018646 in AudioDriverPulseAudio::thread_func(void*) drivers/pulseaudio/audio_driver_pulseaudio.cpp:389
    #5 0x12d570cd in Thread::callback(Thread*, Thread::Settings const&, void (*)(void*), void*) core/os/thread.cpp:77
    #6 0x12d5afc3 in void std::__invoke_impl<void, void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>(std::__invoke_other, void (*&&)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/include/c++/11/bits/invoke.h:61
    #7 0x12d5abd5 in std::__invoke_result<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>::type std::__invoke<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>(void (*&&)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/include/c++/11/bits/invoke.h:96
    #8 0x12d5a645 in void std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> >::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul>) /usr/include/c++/11/bits/std_thread.h:253
    #9 0x12d5a29f in std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> >::operator()() /usr/include/c++/11/bits/std_thread.h:260
    #10 0x12d5a253 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> > >::_M_run() /usr/include/c++/11/bits/std_thread.h:211
    #11 0x13ec9643 in execute_native_thread_routine (/usr/bin/godots+0x13ec9643)
    #12 0x7f4d48c28926 in start_thread nptl/pthread_create.c:435
    #13 0x7f4d48cb89e3 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x1289e3)

0x6160000e2e90 is located 16 bytes inside of 632-byte region [0x6160000e2e80,0x6160000e30f8)
freed by thread T0 here:
    #0 0x7f4d49adb517 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x12d3f2f7 in Memory::free_static(void*, bool) core/os/memory.cpp:168
    #2 0x19aaa03 in void memdelete<Object>(Object*) core/os/memory.h:118
    #3 0xcd0db11 in SceneTree::_flush_delete_queue() scene/main/scene_tree.cpp:1094
    #4 0xccfbed0 in SceneTree::idle(float) scene/main/scene_tree.cpp:545
    #5 0x199f6ae in Main::iteration() main/main.cpp:2186
    #6 0x186aee7 in OS_X11::run() platform/x11/os_x11.cpp:3641
    #7 0x17cfd53 in main platform/x11/godot_x11.cpp:55
    #8 0x7f4d48bbdfcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

previously allocated by thread T0 here:
    #0 0x7f4d49adb867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x12d3e231 in Memory::alloc_static(unsigned long, bool) core/os/memory.cpp:75
    #2 0x12d3e142 in operator new(unsigned long, char const*) core/os/memory.cpp:40
    #3 0xcb373d4 in Object* ClassDB::creator<AudioStreamPlayer>() core/class_db.h:140
    #4 0x12519d3e in ClassDB::instance(StringName const&) core/class_db.cpp:520
    #5 0x1ca406b in GDScriptNativeClass::instance() modules/gdscript/gdscript.cpp:77
    #6 0x1ca3a29 in GDScriptNativeClass::_new() modules/gdscript/gdscript.cpp:65
    #7 0x1d88b09 in MethodBind0R<Variant>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:237
    #8 0x127ad6e9 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:918
    #9 0x12a5172f in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1175
    #10 0x1ead0e0 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1044
    #11 0x1ccab59 in GDScriptInstance::call_multilevel(StringName const&, Variant const**, int) modules/gdscript/gdscript.cpp:1184
    #12 0xcbcc811 in Node::_notification(int) scene/main/node.cpp:56
    #13 0x1b69bdf in Node::_notificationv(int, bool) scene/main/node.h:45
    #14 0x1b6c198 in CanvasItem::_notificationv(int, bool) scene/2d/canvas_item.h:163
    #15 0xca3e93e in Node2D::_notificationv(int, bool) scene/2d/node_2d.h:37
    #16 0x127adb9b in Object::notification(int, bool) core/object.cpp:927
    #17 0xcd0ac37 in SceneTree::_notify_group_pause(StringName const&, int) scene/main/scene_tree.cpp:977
    #18 0xccfa869 in SceneTree::idle(float) scene/main/scene_tree.cpp:528
    #19 0x199f6ae in Main::iteration() main/main.cpp:2186
    #20 0x186aee7 in OS_X11::run() platform/x11/os_x11.cpp:3641
    #21 0x17cfd53 in main platform/x11/godot_x11.cpp:55
    #22 0x7f4d48bbdfcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

Thread T3 created by T0 here:
    #0 0x7f4d49a7f685 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:216
    #1 0x13ec9919 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/usr/bin/godots+0x13ec9919)
    #2 0x12d575e3 in Thread::start(void (*)(void*), void*, Thread::Settings const&) core/os/thread.cpp:93
    #3 0x8016a36 in AudioDriverPulseAudio::init() drivers/pulseaudio/audio_driver_pulseaudio.cpp:340
    #4 0x10812a11 in AudioDriverManager::initialize(int) servers/audio_server.cpp:200
    #5 0x17f2445 in OS_X11::initialize(OS::VideoMode const&, int, int) platform/x11/os_x11.cpp:600
    #6 0x197cc82 in Main::setup2(unsigned long) main/main.cpp:1299
    #7 0x1976fcd in Main::setup(char const*, int, char**, bool) main/main.cpp:1224
    #8 0x17cfc55 in main platform/x11/godot_x11.cpp:48
    #9 0x7f4d48bbdfcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-use-after-free scene/audio/audio_stream_player.h:72 in AudioStreamPlayer::_mix_audios(void*)

This example was found by fuzzer, so it is quite unlikelly that this code could be used in real project, but still this should be handled gracefully.

Steps to reproduce

Above

Minimal reproduction project

No response

@qarmin qarmin changed the title Freeing AudioStreamPlayer cause crash due using them in different thread Freeing AudioStreamPlayer cause crash due using it in different thread Oct 21, 2021
@qarmin
Copy link
Contributor Author

qarmin commented Oct 5, 2022

Still crashes with v3.6.beta.custom_build. cbde08d, but not with 4.0.beta.custom_build. 321251a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant