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

Segmentation fault when setting exported value to self in imported resource #60590

Closed
Jummit opened this issue Apr 28, 2022 · 3 comments · Fixed by #68281
Closed

Segmentation fault when setting exported value to self in imported resource #60590

Jummit opened this issue Apr 28, 2022 · 3 comments · Fixed by #68281

Comments

@Jummit
Copy link
Contributor

Jummit commented Apr 28, 2022

Godot version

3.4.4

System information

Linux

Issue description

When writing a custom importer plugin that imports a resource which sets a member to self Godot crashes with a segmentation fault. This happens when the value is set to self directly, or when used inside another datatype like a dictionary or array.

This is expected to fail, but should not lead to a segfault.

Steps to reproduce

Write a resource importer and set a member to self in the imported resource.

extends Resource

export var value: Resource

func _init() -> void:
	value = self
	# segfault

Minimal reproduction project

This project crashes when trying to import test.json.

Dictionary Crash.zip

@Calinou
Copy link
Member

Calinou commented Apr 28, 2022

I can confirm this on 3.5.beta 59e84be.

The crash handler fails to kick in, so I don't get a backtrace automatically. Running the editor binary through GDB reveals the following backtrace:

(gdb) bt
#0  0x0000000006261ad3 in Memory::alloc_static (p_bytes=64, p_pad_align=true) at core/os/memory.cpp:75
#1  0x0000000002f2bad6 in CowData<wchar_t>::resize (this=0x7fffff7ff4d0, p_size=10) at ./core/cowdata.h:278
#2  0x0000000003e6d07b in String::resize (this=0x7fffff7ff4d0, p_size=10) at ./core/ustring.h:157
#3  0x000000000616a3be in String::copy_from (this=0x7fffff7ff4d0, p_cstr=0x27fe3e5 "Reference") at core/ustring.cpp:230
#4  0x000000000617031a in String::String (this=0x7fffff7ff4d0, p_str=0x27fe3e5 "Reference") at core/ustring.cpp:1691
#5  0x000000000297b1e2 in Reference::get_class_static () at ./core/reference.h:40
#6  0x000000000297b4db in Reference::_get_property_listv (this=0x12c2c3a0, p_list=0x7fffff7ff988, p_reversed=false) at ./core/reference.h:40
#7  0x0000000002b6d8c7 in Resource::_get_property_listv (this=0x12c2c3a0, p_list=0x7fffff7ff988, p_reversed=false) at ./core/resource.h:49
#8  0x00000000060e44e1 in Object::get_property_list (this=0x12c2c3a0, p_list=0x7fffff7ff988, p_reversed=false) at core/object.cpp:646
#9  0x00000000063918aa in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1566
#10 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#11 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#12 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#13 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#14 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#15 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#16 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#17 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#18 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#19 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#20 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#21 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#22 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#23 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#24 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#25 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#26 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#27 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#28 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#29 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#30 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#31 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#32 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#33 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#34 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#35 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#36 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#37 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#38 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#39 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#40 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#41 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#42 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#43 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#44 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#45 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#46 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#47 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#48 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#49 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#50 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582

[ ... thousands of similar instances ... ]

#13393 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#13394 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#13395 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#13396 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#13397 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
#13398 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=true) at core/io/resource_format_binary.cpp:1582
#13399 0x00000000063926c9 in ResourceFormatSaverBinaryInstance::save (this=0x7fffffff7cb8, p_path=..., p_resource=..., p_flags=0) at core/io/resource_format_binary.cpp:1679


#13400 0x00000000063948c7 in ResourceFormatSaverBinary::save (this=0x6ce8d80, p_path=..., p_resource=..., p_flags=0) at core/io/resource_format_binary.cpp:1860
#13401 0x00000000063b00e1 in ResourceSaver::save (p_path=..., p_resource=..., p_flags=0) at core/io/resource_saver.cpp:116
#13402 0x00000000063d919e in _ResourceSaver::save (this=0x6d60bf0, p_path=..., p_resource=..., p_flags=0) at core/bind/core_bind.cpp:142
#13403 0x0000000006411d7d in MethodBind3R<Error, String const&, Ref<Resource> const&, _ResourceSaver::SaverFlags>::call (this=0x6d61040, p_object=0x6d60bf0, p_args=0x7fffffff8368, p_arg_count=2, r_error=...) at ./core/method_bind.gen.inc:2453
#13404 0x00000000060e64dd in Object::call (this=0x6d60bf0, p_method=..., p_args=0x7fffffff8368, p_argcount=2, r_error=...) at core/object.cpp:918

#13405 0x000000000619c2b8 in Variant::call_ptr (this=0x8a0fbd0, p_method=..., p_args=0x7fffffff8368, p_argcount=2, r_ret=0x7fffffff8308, r_error=...) at core/variant_call.cpp:1193

#13406 0x0000000002ffd481 in GDScriptFunction::call (this=0x113727b0, p_instance=0x1135efe0, p_args=0x7fffffffa020, p_argcount=5, r_err=..., p_state=0x0) at modules/gdscript/gdscript_function.cpp:1048
#13407 0x0000000002f9dfcd in GDScriptInstance::call (this=0x1135efe0, p_method=..., p_args=0x7fffffffa020, p_argcount=5, r_error=...) at modules/gdscript/gdscript.cpp:1196
#13408 0x0000000006149645 in ScriptInstance::call (this=0x1135efe0, p_method=..., p_arg1=..., p_arg2=..., p_arg3=..., p_arg4=..., p_arg5=..., p_arg6=..., p_arg7=..., p_arg8=...) at core/script_language.cpp:311
#13409 0x00000000047a8b01 in EditorImportPlugin::import (this=0x112ae7c0, p_source_file=..., p_save_path=..., p_options=..., r_platform_variants=0x7fffffffaac0, r_gen_files=0x7fffffffaab8, r_metadata=0x7fffffffaaa0) at editor/import/editor_import_plugin.cpp:142
#13410 0x000000000423e6d5 in EditorFileSystem::_reimport_file (this=0x94384d0, p_file=...) at editor/editor_file_system.cpp:1756
#13411 0x0000000004232418 in EditorFileSystem::reimport_files (this=0x94384d0, p_files=...) at editor/editor_file_system.cpp:1961
#13412 0x0000000004231583 in EditorFileSystem::_update_scan_actions (this=0x94384d0) at editor/editor_file_system.cpp:574

#13413 0x0000000004236d01 in EditorFileSystem::_notification (this=0x94384d0, p_what=17) at editor/editor_file_system.cpp:1126
#13414 0x00000000042460b1 in EditorFileSystem::_notificationv (this=0x94384d0, p_notification=17, p_reversed=false) at editor/editor_file_system.h:111
#13415 0x00000000060e2df0 in Object::notification (this=0x94384d0, p_notification=17, p_reversed=false) at core/object.cpp:927

#13416 0x0000000004e0546f in SceneTree::_notify_group_pause (this=0x893c950, p_group=..., p_notification=17) at scene/main/scene_tree.cpp:1057
#13417 0x0000000004e05935 in SceneTree::idle (this=0x893c950, p_time=0.150000095) at scene/main/scene_tree.cpp:596
#13418 0x0000000002969f98 in Main::iteration () at main/main.cpp:2273
#13419 0x000000000291f799 in OS_X11::run (this=0x7fffffffc120) at platform/x11/os_x11.cpp:3933
#13420 0x0000000002908ce3 in main (argc=2, argv=0x7fffffffca18) at platform/x11/godot_x11.cpp:55

Full backtrace:

(gdb) bt full
#0  0x0000000006261ad3 in Memory::alloc_static (p_bytes=64, p_pad_align=true) at core/os/memory.cpp:75
        prepad = true
        mem = 0x0
#1  0x0000000002f2bad6 in CowData<wchar_t>::resize (this=0x7fffff7ff4d0, p_size=10) at ./core/cowdata.h:278
        ptr = 0xffff118d3bd0
        current_size = 0
        rc = 0
        current_alloc_size = 0
        alloc_size = 64
#2  0x0000000003e6d07b in String::resize (this=0x7fffff7ff4d0, p_size=10) at ./core/ustring.h:157
No locals.
#3  0x000000000616a3be in String::copy_from (this=0x7fffff7ff4d0, p_cstr=0x27fe3e5 "Reference") at core/ustring.cpp:230
        len = 9
        dst = 0x7fffff7ff9e8 L""
#4  0x000000000617031a in String::String (this=0x7fffff7ff4d0, p_str=0x27fe3e5 "Reference") at core/ustring.cpp:1691
No locals.
#5  0x000000000297b1e2 in Reference::get_class_static () at ./core/reference.h:40
No locals.
#6  0x000000000297b4db in Reference::_get_property_listv (this=0x12c2c3a0, p_list=0x7fffff7ff988, p_reversed=false) at ./core/reference.h:40
No locals.
#7  0x0000000002b6d8c7 in Resource::_get_property_listv (this=0x12c2c3a0, p_list=0x7fffff7ff988, p_reversed=false) at ./core/resource.h:49
No locals.
#8  0x00000000060e44e1 in Object::get_property_list (this=0x12c2c3a0, p_list=0x7fffff7ff988, p_reversed=false) at core/object.cpp:646
No locals.
#9  0x00000000063918aa in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1566
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x0}
#10 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
        value = {type = Variant::OBJECT, _data = {_bool = false, _int = 0, _real = 0, _transform2d = 0x0, _aabb = 0x0, _basis = 0x0, _transform = 0x0, _ptr = 0x0, _mem = "\000\000\000\000\000\000\000\000\240\303\302\022\000\000\000"}}
        E = 0x153287c0
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x153281c0}
#11 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
        value = {type = Variant::OBJECT, _data = {_bool = false, _int = 0, _real = 0, _transform2d = 0x0, _aabb = 0x0, _basis = 0x0, _transform = 0x0, _ptr = 0x0, _mem = "\000\000\000\000\000\000\000\000\240\303\302\022\000\000\000"}}
        E = 0x15328250
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x15327c50}
#12 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
        value = {type = Variant::OBJECT, _data = {_bool = false, _int = 0, _real = 0, _transform2d = 0x0, _aabb = 0x0, _basis = 0x0, _transform = 0x0, _ptr = 0x0, _mem = "\000\000\000\000\000\000\000\000\240\303\302\022\000\000\000"}}
        E = 0x15327ce0
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x153276e0}
#13 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
        value = {type = Variant::OBJECT, _data = {_bool = false, _int = 0, _real = 0, _transform2d = 0x0, _aabb = 0x0, _basis = 0x0, _transform = 0x0, _ptr = 0x0, _mem = "\000\000\000\000\000\000\000\000\240\303\302\022\000\000\000"}}
        E = 0x15327770
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x15327170}
#14 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
        value = {type = Variant::OBJECT, _data = {_bool = false, _int = 0, _real = 0, _transform2d = 0x0, _aabb = 0x0, _basis = 0x0, _transform = 0x0, _ptr = 0x0, _mem = "\000\000\000\000\000\000\000\000\240\303\302\022\000\000\000"}}
        E = 0x15327200
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x15326c00}
#15 0x0000000006391be4 in ResourceFormatSaverBinaryInstance::_find_resources (this=0x7fffffff7cb8, p_variant=..., p_main=false) at core/io/resource_format_binary.cpp:1582
        value = {type = Variant::OBJECT, _data = {_bool = false, _int = 0, _real = 0, _transform2d = 0x0, _aabb = 0x0, _basis = 0x0, _transform = 0x0, _ptr = 0x0, _mem = "\000\000\000\000\000\000\000\000\240\303\302\022\000\000\000"}}
        E = 0x15326c90
        res = {reference = 0x12c2c3a0}
        property_list = {_data = 0x15326690}

[ ... thousands of similar instances ... ]

LLDB returns a similar backtrace.

@maximkulkin
Copy link
Contributor

I ran into similar issue of trying to save Resource graph with cycles:

class_name MyResource
extends Resource

export var other: Resource

When having resources like this

var a = MyResource.new()
var b = MyResource.new()
a.other = b
b.other = a
ResourceSaver.save("res://saved.tres", a)

It crashes. It also crashes if there is a longer loop: "A -> B -> C -> A".

If you pass a ResourceSaver.FLAG_CHANGE_PATH and the loop is full, it will not crash, will print error about circular references in console, will break the loop by replacing one of the references with null and save successfully:

var a = MyResource.new()
var b = MyResource.new()
var c = MyResource.new()
a.other = b
b.other = c
c.other = a
ResourceSaver.save("res://saved.tres", a, ResourceSaver.FLAG_CHANGE_PATH)

However, if the loop is not full, it just crashes:

var a = MyResource.new()
var b = MyResource.new()
var c = MyResource.new()
a.other = b
b.other = c
c.other = b
ResourceSaver.save("res://saved.tres", a, ResourceSaver.FLAG_CHANGE_PATH)

The bug reproduces on both text (.tres) and binary (.res) resources, in Godot 3.5 [991bb6a] and in Godot 4.0.beta3 [01ae26d].

Expected behavior: it dumps all resources as if there were no loops (and does a better job of tracking which resources were already saved to avoid infinite recursion and eventual crash). Some resource might have references to other resources that are found later in the resource file. When loading, it instantiates and initializes resources as usual, except for references to resources that haven't been seen yet are postponed until all resources are initialized.

@maximkulkin
Copy link
Contributor

I am working on a fix that will a) stop Godot from crashing when saving resources with circular references; b) allow saving and loading resources with circular references. So far I have successfully implemented fix on text format saver (ResourceFormatSaverText). Will need to do more tests (especially regarding saving/loading packed scenes) and then make the same change to binary format.

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

Successfully merging a pull request may close this issue.

4 participants