godot icon indicating copy to clipboard operation
godot copied to clipboard

`load_threaded_request` cause crashes in NoiseTexture2D destructor when item leaks

Open qarmin opened this issue 3 years ago • 2 comments

Godot version

4.0.beta.custom_build. f3e6750a7

System information

Ubuntu 22.04 - Radeon RX 570, Gnome shell 42 X11

Issue description

Running multiple times load_threaded_request and closing app, Valgrind shows this info(asan and ubsan not prints anything)

ERROR: 1 RID allocations of type 'PN13RendererDummy14TextureStorage12DummyTextureE' were leaked at exit.
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
     at: cleanup (core/object/object.cpp:1999)
ERROR: Resources still in use at exit (run with --verbose for details).
   at: clear (core/io/resource.cpp:473)
==71027== Invalid read of size 8
==71027==    at 0x38C344C: NoiseTexture2D::~NoiseTexture2D() (noise_texture_2d.cpp:44)
==71027==    by 0x2D10348: void memdelete<RefCounted>(RefCounted*) (memory.h:109)
==71027==    by 0x785CA93: Variant::_clear_internal() (variant.cpp:1354)
==71027==    by 0x26A7218: Variant::clear() (variant.h:302)
==71027==    by 0x26A7291: Variant::~Variant() (variant.h:780)
==71027==    by 0x26E4A5D: CowData<Variant>::_unref(void*) (cowdata.h:213)
==71027==    by 0x26E03D3: CowData<Variant>::~CowData() (cowdata.h:412)
==71027==    by 0x26DAE27: Vector<Variant>::~Vector() (vector.h:287)
==71027==    by 0x65D4A8F: SceneState::~SceneState() (packed_scene.h:37)
==71027==    by 0x46EABF8: void memdelete<SceneState>(SceneState*) (memory.h:109)
==71027==    by 0x46EA773: Ref<SceneState>::unref() (ref_counted.h:221)
==71027==    by 0x46E96B1: Ref<SceneState>::~Ref() (ref_counted.h:233)
==71027==    by 0x65D493F: PackedScene::~PackedScene() (packed_scene.h:207)
==71027==    by 0x26E5691: void memdelete<Resource>(Resource*) (memory.h:109)
==71027==    by 0x26E0E15: Ref<Resource>::unref() (ref_counted.h:221)
==71027==    by 0x26DB8F3: Ref<Resource>::~Ref() (ref_counted.h:233)
==71027==    by 0x778F12B: ResourceLoader::ThreadLoadTask::~ThreadLoadTask() (resource_loader.h:134)
==71027==    by 0x7792C8F: KeyValue<String, ResourceLoader::ThreadLoadTask>::~KeyValue() (pair.h:82)
==71027==    by 0x7792CBF: HashMapElement<String, ResourceLoader::ThreadLoadTask>::~HashMapElement() (hash_map.h:55)
==71027==    by 0x77939AE: void memdelete<HashMapElement<String, ResourceLoader::ThreadLoadTask> >(HashMapElement<String, ResourceLoader::ThreadLoadTask>*) (memory.h:109)
==71027==    by 0x77931AB: DefaultTypedAllocator<HashMapElement<String, ResourceLoader::ThreadLoadTask> >::delete_allocation(HashMapElement<String, ResourceLoader::ThreadLoadTask>*) (memory.h:206)
==71027==    by 0x7794A8C: HashMap<String, ResourceLoader::ThreadLoadTask, HashMapHasherDefault, HashMapComparatorDefault<String>, DefaultTypedAllocator<HashMapElement<String, ResourceLoader::ThreadLoadTask> > >::clear() (hash_map.h:265)
==71027==    by 0x7794945: HashMap<String, ResourceLoader::ThreadLoadTask, HashMapHasherDefault, HashMapComparatorDefault<String>, DefaultTypedAllocator<HashMapElement<String, ResourceLoader::ThreadLoadTask> > >::~HashMap() (hash_map.h:582)
==71027==    by 0xD45B494: __run_exit_handlers (exit.c:113)
==71027==    by 0xD45B60F: exit (exit.c:143)
==71027==    by 0xD43FD96: (below main) (libc_start_call_main.h:74)
==71027==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Steps to reproduce

Run minimal project or load multiple times scene with load_threaded_request that contains NoisyTexture2D

Minimal reproduction project

crash_load_threaded_request.zip

qarmin avatar Dec 06 '22 11:12 qarmin

Without NoisyTexture2D assigned to node this crashes in different place

=================================================================
==74980==ERROR: AddressSanitizer: heap-use-after-free on address 0x62d0000d4268 at pc 0x00001ebd66e7 bp 0x7ffcc04736c0 sp 0x7ffcc04736b0
READ of size 8 at 0x62d0000d4268 thread T0
    #0 0x1ebd66e6 in ObjectDB::remove_instance(Object*) core/object/object.cpp:1966
    #1 0x1ebd16b4 in Object::~Object() core/object/object.cpp:1826
    #2 0x3e6031a in RefCounted::~RefCounted() core/object/ref_counted.h:53
    #3 0x179a0f15 in SceneState::~SceneState() scene/resources/packed_scene.h:37
    #4 0xd40a144 in void memdelete<SceneState>(SceneState*) core/os/memory.h:109
    #5 0xd40837d in Ref<SceneState>::unref() core/object/ref_counted.h:221
    #6 0xd403681 in Ref<SceneState>::~Ref() core/object/ref_counted.h:233
    #7 0x179a04e2 in PackedScene::~PackedScene() scene/resources/packed_scene.h:207
    #8 0x28683bc in void memdelete<Resource>(Resource*) core/os/memory.h:109
    #9 0x284df0d in Ref<Resource>::unref() core/object/ref_counted.h:221
    #10 0x2831849 in Ref<Resource>::~Ref() core/object/ref_counted.h:233
    #11 0x1dbd2c82 in ResourceLoader::ThreadLoadTask::~ThreadLoadTask() core/io/resource_loader.h:134
    #12 0x1dbf3fd5 in KeyValue<String, ResourceLoader::ThreadLoadTask>::~KeyValue() core/templates/pair.h:82
    #13 0x1dbf40f3 in HashMapElement<String, ResourceLoader::ThreadLoadTask>::~HashMapElement() core/templates/hash_map.h:55
    #14 0x1dbf8609 in void memdelete<HashMapElement<String, ResourceLoader::ThreadLoadTask> >(HashMapElement<String, ResourceLoader::ThreadLoadTask>*) core/os/memory.h:109
    #15 0x1dbf5a13 in DefaultTypedAllocator<HashMapElement<String, ResourceLoader::ThreadLoadTask> >::delete_allocation(HashMapElement<String, ResourceLoader::ThreadLoadTask>*) core/os/memory.h:206
    #16 0x1dbfd43c in HashMap<String, ResourceLoader::ThreadLoadTask, HashMapHasherDefault, HashMapComparatorDefault<String>, DefaultTypedAllocator<HashMapElement<String, ResourceLoader::ThreadLoadTask> > >::clear() core/templates/hash_map.h:265
    #17 0x1dbfcb15 in HashMap<String, ResourceLoader::ThreadLoadTask, HashMapHasherDefault, HashMapComparatorDefault<String>, DefaultTypedAllocator<HashMapElement<String, ResourceLoader::ThreadLoadTask> > >::~HashMap() core/templates/hash_map.h:582
    #18 0x7f27300d1494 in __run_exit_handlers stdlib/exit.c:113
    #19 0x7f27300d160f in __GI_exit stdlib/exit.c:143
    #20 0x7f27300b5d96 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:74
    #21 0x7f27300b5e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #22 0x26f14f4 in _start (/usr/bin/godot4s+0x26f14f4)

0x62d0000d4268 is located 7784 bytes inside of 32784-byte region [0x62d0000d2400,0x62d0000da410)
freed by thread T0 here:
    #0 0x7f2730a84517 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 0x1ebd896d in ObjectDB::cleanup() core/object/object.cpp:2032
    #3 0x1d1a2d6e in unregister_core_types() core/register_core_types.cpp:419
    #4 0x293b5e6 in Main::cleanup(bool) main/main.cpp:3446
    #5 0x26f1b4e in main platform/linuxbsd/godot_linuxbsd.cpp:75
    #6 0x7f27300b5d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

previously allocated by thread T0 here:
    #0 0x7f2730a84c18 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:164
    #1 0x1d39eaa9 in Memory::realloc_static(void*, unsigned long, bool) core/os/memory.cpp:129
    #2 0x1ebd5366 in ObjectDB::add_instance(Object*) core/object/object.cpp:1920
    #3 0x1ebdba6a in Object::_construct_object(bool) core/object/object.cpp:1764
    #4 0x1ebccf29 in Object::Object(bool) core/object/object.cpp:1772
    #5 0x1ec2c806 in RefCounted::RefCounted() core/object/ref_counted.cpp:97
    #6 0x5bce093 in GDScriptNativeClass::GDScriptNativeClass(StringName const&) modules/gdscript/gdscript.cpp:59
    #7 0x5c1b701 in GDScriptLanguage::init() modules/gdscript/gdscript.cpp:1991
    #8 0x1ec36dda in ScriptServer::init_languages() core/object/script_language.cpp:203
    #9 0x29137b9 in Main::setup2(unsigned long) main/main.cpp:2374
    #10 0x28ff4aa in Main::setup(char const*, int, char**, bool) main/main.cpp:1880
    #11 0x26f1965 in main platform/linuxbsd/godot_linuxbsd.cpp:61
    #12 0x7f27300b5d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

qarmin avatar Dec 06 '22 11:12 qarmin

Crash not happens when resource not leaks

extends Node2D

var time_to_close: float = 0.3

func _ready():
	ResourceLoader.load_threaded_request("res://NoisyTexture.tscn", "", true, ResourceLoader.CACHE_MODE_IGNORE)

func _process(delta):
	time_to_close -= delta
	print(ResourceLoader.load_threaded_get_status("res://NoisyTexture.tscn"))

	if time_to_close < 0:
		#var ss = ResourceLoader.load_threaded_get("res://NoisyTexture.tscn") # Uncomment this line to fix crash
		get_tree().quit()

qarmin avatar Dec 06 '22 11:12 qarmin

I confirm this issue on master (https://github.com/godotengine/godot/commit/9bd7ad53f7d8b53bb2fa5185f782b6369e38c24a).

adamscott avatar Dec 06 '22 19:12 adamscott