godot icon indicating copy to clipboard operation
godot copied to clipboard

Crash related to tilemaps: malloc(): mismatching next->prev_size (unsorted) / corrupted size vs. prev_size in fastbins

Open furrykef opened this issue 1 year ago • 1 comments

Godot version

4.0.beta7; 4.0.dev (43e9ca40f)

System information

Linux Mint 20.3, GeForce RTX 3060; mobile renderer

Issue description

Sometimes Godot crashes when switching scenes using get_tree().change_scene_to_file(). The crash does not happen inside this function call; it gets a little further before crashing. The bug appears to be related to TileMap or TileSet, since the game where this issue first appeared for me used TileMaps, and the bug disappeared when I removed the TileMaps from my game.

When the crash occurs, no message is printed to the in-editor console, but this does appear in the terminal window if the game is running from when running the editor from the terminal in Godot 4.0.beta7:

malloc(): mismatching next->prev_size (unsorted)

When trying in build 43e9ca40f, I got a different message:

corrupted size vs. prev_size in fastbins

I'm not sure whether using a different build is responsible for the different message, or if it's just crashing in two different places and it's a coincidence that this happened in different builds.

For the test case project, I have two scenes, 1 and 2. Scene 1 uses a tilemap and Scene 2 does not. (This seemed to reproduce the bug more reliably on my system than using two scenes with tilemaps, though the project where I first ran into the bug did use tilemaps in both scenes.) Pressing the 1 key switches to scene 1 (even if it's already loaded), and pressing the 2 key switches to scene 2 (ditto).

Steps to reproduce

  1. Open the project in the editor and run it.
  2. Alternate between the 1 and 2 keys rapidly until the engine crashes, or rapidly press the 1 key a bunch of times and then press the 2 key.

If the bug does not manifest, stop execution and launch again. It seems to happen pretty reliably for me with this project, though.

Minimal reproduction project

scene-switch.zip

furrykef avatar Dec 06 '22 12:12 furrykef

==94676==ERROR: AddressSanitizer: heap-use-after-free on address 0x61f0001c7090 at pc 0x0000168da08d bp 0x7ffe3128aa10 sp 0x7ffe3128aa00
WRITE of size 4 at 0x61f0001c7090 thread T0
    #0 0x168da08c in HashSet<Vector3i, HashMapHasherDefault, HashMapComparatorDefault<Vector3i> >::clear() core/templates/hash_set.h:245
    #1 0x168a1529 in TileMap::_tile_set_changed() scene/2d/tile_map.cpp:4052
    #2 0x1696449c in void call_with_variant_args_helper<TileMap>(TileMap*, void (TileMap::*)(), Variant const**, Callable::CallError&, IndexSequence<>) core/variant/binder_common.h:262
    #3 0x169539e3 in void call_with_variant_args<TileMap>(TileMap*, void (TileMap::*)(), Variant const**, int, Callable::CallError&) core/variant/binder_common.h:376
    #4 0x169424da in CallableCustomMethodPointer<TileMap>::call(Variant const**, int, Variant&, Callable::CallError&) const core/object/callable_method_pointer.h:104
    #5 0x1dfa975c in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:50
    #6 0x1ebacf1c in Object::emit_signalp(StringName const&, Variant const**, int) core/object/object.cpp:1046
    #7 0x7f86a0e in Error Object::emit_signal<>(StringName const&) core/object/object.h:868
    #8 0x1daff655 in Resource::emit_changed() core/io/resource.cpp:44
    #9 0x1854a9df in TileSet::remove_source(int) scene/resources/tile_set.cpp:504
    #10 0x185cfd04 in TileSet::~TileSet() scene/resources/tile_set.cpp:3487
    #11 0x115a438d in void memdelete<TileSet>(TileSet*) core/os/memory.h:109
    #12 0x115a16b3 in Ref<TileSet>::unref() core/object/ref_counted.h:221
    #13 0x1159ed07 in Ref<TileSet>::~Ref() core/object/ref_counted.h:233
    #14 0x168a45e4 in TileMap::~TileMap() scene/2d/tile_map.cpp:4073
    #15 0x644c172 in void memdelete<Node>(Node*) core/os/memory.h:109
    #16 0x13827ca9 in Node::_notification(int) scene/main/node.cpp:169
    #17 0x492dcb9 in Node::_notificationv(int, bool) scene/main/node.h:45
    #18 0x7656980 in CanvasItem::_notificationv(int, bool) scene/main/canvas_item.h:45
    #19 0x133e1862 in Node2D::_notificationv(int, bool) scene/2d/node_2d.h:37
    #20 0x1eba285e in Object::notification(int, bool) core/object/object.cpp:790
    #21 0x1eb8f72e in Object::_predelete() core/object/object.cpp:196
    #22 0x1ebd2d23 in predelete_handler(Object*) core/object/object.cpp:1842
    #23 0x644bf9e in void memdelete<Node>(Node*) core/os/memory.h:105
    #24 0x1398abfd in SceneTree::_change_scene(Node*) scene/main/scene_tree.cpp:1096
    #25 0xd7c08d4 in void call_with_variant_args_helper<__UnexistingClass, Node*, 0ul>(__UnexistingClass*, void (__UnexistingClass::*)(Node*), Variant const**, Callable::CallError&, IndexSequence<0ul>) core/variant/binder_common.h:262
    #26 0xd7b8cdc in void call_with_variant_args_dv<__UnexistingClass, Node*>(__UnexistingClass*, void (__UnexistingClass::*)(Node*), Variant const**, int, Callable::CallError&, Vector<Variant> const&) core/variant/binder_common.h:409
    #27 0xd79b776 in MethodBindT<Node*>::call(Object*, Variant const**, int, Callable::CallError&) const core/object/method_bind.h:320
    #28 0x1eba130a in Object::callp(StringName const&, Variant const**, int, Callable::CallError&) core/object/object.cpp:733
    #29 0x1dfaa195 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:62
    #30 0x1eb7a3ff in MessageQueue::_call_function(Callable const&, Variant const*, int, bool) core/object/message_queue.cpp:229
    #31 0x1eb7b4f2 in MessageQueue::flush() core/object/message_queue.cpp:275
    #32 0x13974451 in SceneTree::physics_process(double) scene/main/scene_tree.cpp:430
    #33 0x2934574 in Main::iteration() main/main.cpp:3166
    #34 0x2714b89 in OS_LinuxBSD::run() platform/linuxbsd/os_linuxbsd.cpp:878
    #35 0x26f1b44 in main platform/linuxbsd/godot_linuxbsd.cpp:73
    #36 0x7f5a7bcc7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #37 0x7f5a7bcc7e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #38 0x26f14f4 in _start (/usr/bin/godot4s+0x26f14f4)

0x61f0001c7090 is located 16 bytes inside of 3092-byte region [0x61f0001c7080,0x61f0001c7c94)
freed by thread T0 here:
    #0 0x7f5a7c696517 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x1d39eedb in Memory::free_static(void*, bool) core/os/memory.cpp:168
    #2 0x168db126 in HashSet<Vector3i, HashMapHasherDefault, HashMapComparatorDefault<Vector3i> >::~HashSet() core/templates/hash_set.h:471
    #3 0x168a4449 in TileMap::~TileMap() scene/2d/tile_map.cpp:4073
    #4 0x644c172 in void memdelete<Node>(Node*) core/os/memory.h:109
    #5 0x13827ca9 in Node::_notification(int) scene/main/node.cpp:169
    #6 0x492dcb9 in Node::_notificationv(int, bool) scene/main/node.h:45
    #7 0x7656980 in CanvasItem::_notificationv(int, bool) scene/main/canvas_item.h:45
    #8 0x133e1862 in Node2D::_notificationv(int, bool) scene/2d/node_2d.h:37
    #9 0x1eba285e in Object::notification(int, bool) core/object/object.cpp:790
    #10 0x1eb8f72e in Object::_predelete() core/object/object.cpp:196
    #11 0x1ebd2d23 in predelete_handler(Object*) core/object/object.cpp:1842
    #12 0x644bf9e in void memdelete<Node>(Node*) core/os/memory.h:105
    #13 0x1398abfd in SceneTree::_change_scene(Node*) scene/main/scene_tree.cpp:1096
    #14 0xd7c08d4 in void call_with_variant_args_helper<__UnexistingClass, Node*, 0ul>(__UnexistingClass*, void (__UnexistingClass::*)(Node*), Variant const**, Callable::CallError&, IndexSequence<0ul>) core/variant/binder_common.h:262
    #15 0xd7b8cdc in void call_with_variant_args_dv<__UnexistingClass, Node*>(__UnexistingClass*, void (__UnexistingClass::*)(Node*), Variant const**, int, Callable::CallError&, Vector<Variant> const&) core/variant/binder_common.h:409
    #16 0xd79b776 in MethodBindT<Node*>::call(Object*, Variant const**, int, Callable::CallError&) const core/object/method_bind.h:320
    #17 0x1eba130a in Object::callp(StringName const&, Variant const**, int, Callable::CallError&) core/object/object.cpp:733
    #18 0x1dfaa195 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:62
    #19 0x1eb7a3ff in MessageQueue::_call_function(Callable const&, Variant const*, int, bool) core/object/message_queue.cpp:229
    #20 0x1eb7b4f2 in MessageQueue::flush() core/object/message_queue.cpp:275
    #21 0x13974451 in SceneTree::physics_process(double) scene/main/scene_tree.cpp:430
    #22 0x2934574 in Main::iteration() main/main.cpp:3166
    #23 0x2714b89 in OS_LinuxBSD::run() platform/linuxbsd/os_linuxbsd.cpp:878
    #24 0x26f1b44 in main platform/linuxbsd/godot_linuxbsd.cpp:73
    #25 0x7f5a7bcc7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

previously allocated by thread T0 here:
    #0 0x7f5a7c696867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x1d39ddfd in Memory::alloc_static(unsigned long, bool) core/os/memory.cpp:75
    #2 0x16915d36 in HashSet<Vector3i, HashMapHasherDefault, HashMapComparatorDefault<Vector3i> >::_resize_and_rehash(unsigned int) core/templates/hash_set.h:151
    #3 0x168f3181 in HashSet<Vector3i, HashMapHasherDefault, HashMapComparatorDefault<Vector3i> >::_insert(Vector3i const&) core/templates/hash_set.h:192
    #4 0x168c3bb5 in HashSet<Vector3i, HashMapHasherDefault, HashMapComparatorDefault<Vector3i> >::insert(Vector3i const&) core/templates/hash_set.h:408
    #5 0x1683ecaf in TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List&) scene/2d/tile_map.cpp:1882
    #6 0x1680839a in TileMap::_update_dirty_quadrants() scene/2d/tile_map.cpp:852
    #7 0x41779cb in void call_with_variant_args_helper<__UnexistingClass>(__UnexistingClass*, void (__UnexistingClass::*)(), Variant const**, Callable::CallError&, IndexSequence<>) core/variant/binder_common.h:262
    #8 0x41713c7 in void call_with_variant_args_dv<__UnexistingClass>(__UnexistingClass*, void (__UnexistingClass::*)(), Variant const**, int, Callable::CallError&, Vector<Variant> const&) core/variant/binder_common.h:409
    #9 0x415e58e in MethodBindT<>::call(Object*, Variant const**, int, Callable::CallError&) const core/object/method_bind.h:320
    #10 0x1eba130a in Object::callp(StringName const&, Variant const**, int, Callable::CallError&) core/object/object.cpp:733
    #11 0x1dfaa195 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:62
    #12 0x1eb7a3ff in MessageQueue::_call_function(Callable const&, Variant const*, int, bool) core/object/message_queue.cpp:229
    #13 0x1eb7b4f2 in MessageQueue::flush() core/object/message_queue.cpp:275
    #14 0x13974451 in SceneTree::physics_process(double) scene/main/scene_tree.cpp:430
    #15 0x2934574 in Main::iteration() main/main.cpp:3166
    #16 0x2714b89 in OS_LinuxBSD::run() platform/linuxbsd/os_linuxbsd.cpp:878
    #17 0x26f1b44 in main platform/linuxbsd/godot_linuxbsd.cpp:73
    #18 0x7f5a7bcc7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-use-after-free core/templates/hash_set.h:245 in HashSet<Vector3i, HashMapHasherDefault, HashMapComparatorDefault<Vector3i> >::clear()

qarmin avatar Dec 06 '22 13:12 qarmin

This sounds kind of similar to the issue I had. It might be fixed with #69922.

vmedea avatar Dec 13 '22 22:12 vmedea

I can't reproduce the crash in the master build anymore, so I assume it has indeed been fixed.

furrykef avatar Dec 14 '22 04:12 furrykef

@qarmin How do you get a stack trace like that? I'm having corrupted size vs. prev_size in fastbins crashes in Godot 4 stable but don't get any error messages like that.

naturally-intelligent avatar Mar 07 '23 14:03 naturally-intelligent