godotengine / godot

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

[Qodot] Godot crashes with a stack trace when building a map with large amount of textures #61592

Open KometFox opened 2 years ago

KometFox commented 2 years ago

Godot version

3.4.4 Stable

System information

Ubuntu 22.04 Jammy (Linux), GLES 3.0

Issue description

When trying to full build or quick build a map with the Qodot addon whose map is imported from Trenchbroom Godot crashes with this error:

Building /home/kruz/Dokumente/Programme/3D/Godot/Project/3DTankGame/Base/Maps/Village/Village2.map

*** stack smashing detected ***: terminated

This happens when the Trenchbroom map in question has tons of textures being loaded in textures entry. Qodot addon doesn't have any line of code related to stack smashing.

What I excepted to to work: That Godot would handle the map just fine without any error or crashes.

Steps to reproduce

  1. Download the reproduction project
  2. Open the MapScene file
  3. Click on the Qodot node and press Quick Build or Full Build
  4. Godot will now crash with stack smashing error.

Minimal reproduction project

GitHub for some reason wont let me upload this zip file so I have to use a 3rd party service for that instead, the link expires in 14 days. Godot Project

qarmin commented 2 years ago

This looks like issue with Qodot not Godot

==9520==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d0013a1210 at pc 0x7f4b0764003d bp 0x7ffec9183ef0 sp 0x7ffec9183698
READ of size 65 at 0x60d0013a1210 thread T0
    #0 0x7f4b0764003c in __interceptor_fopen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:5718
    #1 0x7f4acb0064bb in map_parser_load src/c/map_parser.c:122
    #2 0x7f4acb401817 in qodot_load_map src/c/qodot.c:115
    #3 0x343580c in NativeScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdnative/nativescript/nativescript.cpp:731
    #4 0x12ab01c7 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:899
    #5 0x12d53970 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1185
    #6 0x1f0b2c2 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1050
    #7 0x1d399f3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1196
    #8 0x12ab01c7 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:899
    #9 0x12aae1a3 in Object::callv(StringName const&, Array const&) core/object.cpp:827
    #10 0x12b17f86 in MethodBind2R<Variant, StringName const&, Array const&>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:1681
    #11 0x12ab065a in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:918
    #12 0x12d53970 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1185
    #13 0x1f0b241 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1048
    #14 0x1d399f3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1196
    #15 0x12ab01c7 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:899
    #16 0x12d53970 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1185
    #17 0x1f0b241 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1048
    #18 0x1f2888c in GDScriptFunctionState::resume(Variant const&) modules/gdscript/gdscript_function.cpp:1814
    #19 0x1f261f8 in GDScriptFunctionState::_signal_callback(Variant const**, int, Variant::CallError&) modules/gdscript/gdscript_function.cpp:1762
    #20 0x1f50cf7 in MethodBindVarArg<GDScriptFunctionState>::call(Object*, Variant const**, int, Variant::CallError&) (/usr/bin/godots+0x1f50cf7)
    #21 0x12ab065a in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:918
    #22 0x12abad98 in Object::emit_signal(StringName const&, Variant const**, int) core/object.cpp:1231
    #23 0x12abce84 in Object::emit_signal(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) core/object.cpp:1286
    #24 0xd04b0ee in SceneTree::idle(float) scene/main/scene_tree.cpp:638
    #25 0x1a18d22 in Main::iteration() main/main.cpp:2271
    #26 0x18e7b7b in OS_X11::run() platform/x11/os_x11.cpp:3842
    #27 0x184b109 in main platform/x11/godot_x11.cpp:55
    #28 0x7f4b06a7fd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    #29 0x7f4b06a7fe3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #30 0x184ad1d in _start (/usr/bin/godots+0x184ad1d)

0x60d0013a1210 is located 16 bytes inside of 144-byte region [0x60d0013a1200,0x60d0013a1290)
freed by thread T0 here:
    #0 0x7f4b076d046f in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:122
    #1 0x130573de in Memory::free_static(void*, bool) core/os/memory.cpp:168
    #2 0x190abc8 in CowData<char>::_unref(void*) core/cowdata.h:209
    #3 0x18fdf70 in CowData<char>::~CowData() core/cowdata.h:375
    #4 0x18f9f21 in CharString::~CharString() core/ustring.h:78
    #5 0x4ad3acf in godot_char_string_destroy modules/gdnative/gdnative/string.cpp:62
    #6 0x7f4acb40180f in qodot_load_map src/c/qodot.c:113
    #7 0x7ffec918456f  ([stack]+0x2256f)
    #8 0x7ffec918461f  ([stack]+0x2261f)

previously allocated by thread T0 here:
    #0 0x7f4b076d0868 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
    #1 0x1305639b in Memory::alloc_static(unsigned long, bool) core/os/memory.cpp:75
    #2 0x1990bbd in CowData<char>::resize(int) core/cowdata.h:278
    #3 0x1986a65 in CharString::resize(int) core/ustring.h:86
    #4 0x12cad66d in String::utf8() const core/ustring.cpp:1630
    #5 0x4adffba in godot_string_utf8 modules/gdnative/gdnative/string.cpp:973
    #6 0x7f4acb4017e3 in qodot_load_map src/c/qodot.c:110
    #7 0x7ffec918456f  ([stack]+0x2256f)
    #8 0x7ffec918461f  ([stack]+0x2261f)
KometFox commented 2 years ago

Well I talked with them on their Discord channel and they told to me I should open a Issue for that on Godot issue tracker page, not on Qodot one.

qarmin commented 2 years ago

This may be Godot GDNative bug, but I'm not convinced about it In line https://github.com/QodotPlugin/libqodot/blob/ddae1861921b0cc10063ed9b8a76d049d5d674fd/src/c/qodot.c#L110

godot_char_string map_file_char_str = api->godot_string_utf8(&map_file_str);

variable is created, here destroyed https://github.com/QodotPlugin/libqodot/blob/ddae1861921b0cc10063ed9b8a76d049d5d674fd/src/c/qodot.c#L113

api->godot_char_string_destroy(&map_file_char_str);

and used again(freed memory) https://github.com/QodotPlugin/libmap/blob/6e4160924cf5373e67e8f35422b196e6e0eaa52c/src/c/map_parser.c#L122

    FILE *map = fopen(map_file, "r");