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

GDScript PR #90601 broke addon compatibility and segfaults #92021

Closed
Ebbo opened this issue May 16, 2024 · 14 comments · Fixed by #92035 or #93166
Closed

GDScript PR #90601 broke addon compatibility and segfaults #92021

Ebbo opened this issue May 16, 2024 · 14 comments · Fixed by #92035 or #93166

Comments

@Ebbo
Copy link

Ebbo commented May 16, 2024

Tested versions

v4.3.dev6.official 64520fe

System information

Linux, Windows & macos

Issue description

If you run the MRP from the editor, it works no problem, but when trying to run the project exported it crashes. This wasn't the case in previous versions.
Enabling the Plugin and exporting the Project causes a segfault during runtime.

Steps to reproduce

Open project -> reboot to bypass the plugin loading bug -> run the project normally from the editor ✅
Open project -> export it -> run the exported project 🚫

Minimal reproduction project (MRP)

https://github.com/godotengine/godot/files/15337905/reprobug.zip

@Ebbo Ebbo changed the title Godot 4.3 Pull Request 90601 broke addon compatiblty and segfaults Godot 4.3 Pull Request 90601 broke addon compatibility and segfaults May 16, 2024
@coppolaemilio coppolaemilio added this to the 4.3 milestone May 16, 2024
@clayjohn clayjohn moved this from Unassessed to Release Blocker in 4.x Release Blockers May 16, 2024
@dalexeev
Copy link
Member

CC @rune-scape @adamscott (you commented on #90601 today)

@rune-scape
Copy link
Contributor

reproduced it with a stacktrace on windows template_debug 64520fe
the crash happens in "res://addons/dialogic/Core/DialogicResourceUtil.gd" at line 121:
static var label_cache := {}
it seems the static variables didnt get initialized (they were all nil at the time of the crash), but the gdscript vm assumes they were, so the crash happens bc of a null dereference in dictionary.cpp
this is the only place static vars are used, im guessing static vars aren't being initialized anywhere, but only in export templates for some reason

stacktrace:

app.exe!HashMap<Variant,Variant,VariantHasher,StringLikeVariantComparator,DefaultTypedAllocator<HashMapElement<Variant,Variant>>>::size() Line 246
	at C:\git\godot\core\templates\hash_map.h(246)
app.exe!Dictionary::is_empty() Line 167
	at C:\git\godot\core\variant\dictionary.cpp(167)
app.exe!call_with_validated_variant_args_retc_helper<Dictionary,bool>(Dictionary * p_instance, bool(const Dictionary::*)() p_method, const Variant * * p_args, Variant * r_ret, IndexSequence<> __formal) Line 380
	at C:\git\godot\core\variant\binder_common.h(380)
app.exe!call_with_validated_variant_args_retc<Dictionary,bool>(Variant * base, bool(const Dictionary::*)() p_method, const Variant * * p_args, Variant * r_ret) Line 626
	at C:\git\godot\core\variant\binder_common.h(626)
app.exe!vc_validated_call<bool,Dictionary>(bool(const Dictionary::*)() method, Variant * base, const Variant * * p_args, Variant * r_ret) Line 120
	at C:\git\godot\core\variant\variant_call.cpp(120)
app.exe!`_register_variant_builtin_methods'::`2'::Method_Dictionary_is_empty::validated_call(Variant * base, const Variant * * p_args, int p_argcount, Variant * r_ret) Line 2212
	at C:\git\godot\core\variant\variant_call.cpp(2212)
app.exe!GDScriptFunction::call(GDScriptInstance * p_instance, const Variant * * p_args, int p_argcount, Callable::CallError & r_err, GDScriptFunction::CallState * p_state) Line 2080
	at C:\git\godot\modules\gdscript\gdscript_vm.cpp(2080)
app.exe!GDScript::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 886
	at C:\git\godot\modules\gdscript\gdscript.cpp(886)
app.exe!Variant::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Variant & r_ret, Callable::CallError & r_error) Line 1212
	at C:\git\godot\core\variant\variant_call.cpp(1212)
app.exe!GDScriptFunction::call(GDScriptInstance * p_instance, const Variant * * p_args, int p_argcount, Callable::CallError & r_err, GDScriptFunction::CallState * p_state) Line 1717
	at C:\git\godot\modules\gdscript\gdscript_vm.cpp(1717)
app.exe!GDScript::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 886
	at C:\git\godot\modules\gdscript\gdscript.cpp(886)
app.exe!Variant::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Variant & r_ret, Callable::CallError & r_error) Line 1212
	at C:\git\godot\core\variant\variant_call.cpp(1212)
app.exe!GDScriptFunction::call(GDScriptInstance * p_instance, const Variant * * p_args, int p_argcount, Callable::CallError & r_err, GDScriptFunction::CallState * p_state) Line 1746
	at C:\git\godot\modules\gdscript\gdscript_vm.cpp(1746)
app.exe!GDScript::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 886
	at C:\git\godot\modules\gdscript\gdscript.cpp(886)
app.exe!Variant::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Variant & r_ret, Callable::CallError & r_error) Line 1212
	at C:\git\godot\core\variant\variant_call.cpp(1212)
app.exe!GDScriptFunction::call(GDScriptInstance * p_instance, const Variant * * p_args, int p_argcount, Callable::CallError & r_err, GDScriptFunction::CallState * p_state) Line 1746
	at C:\git\godot\modules\gdscript\gdscript_vm.cpp(1746)
app.exe!GDScriptInstance::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 1978
	at C:\git\godot\modules\gdscript\gdscript.cpp(1978)
app.exe!Node::_gdvirtual__ready_call<0>() Line 354
	at C:\git\godot\scene\main\node.h(354)
app.exe!Node::_notification(int p_notification) Line 214
	at C:\git\godot\scene\main\node.cpp(214)
app.exe!Node::_notificationv(int p_notification, bool p_reversed) Line 49
	at C:\git\godot\scene\main\node.h(49)
app.exe!Object::notification(int p_notification, bool p_reversed) Line 907
	at C:\git\godot\core\object\object.cpp(907)
app.exe!Node::_propagate_ready() Line 269
	at C:\git\godot\scene\main\node.cpp(269)
app.exe!Node::_propagate_ready() Line 260
	at C:\git\godot\scene\main\node.cpp(260)
app.exe!Node::_set_tree(SceneTree * p_tree) Line 3181
	at C:\git\godot\scene\main\node.cpp(3181)
app.exe!SceneTree::initialize() Line 450
	at C:\git\godot\scene\main\scene_tree.cpp(450)
app.exe!OS_Windows::run() Line 1684
	at C:\git\godot\platform\windows\os_windows.cpp(1684)
app.exe!widechar_main(int argc, wchar_t * * argv) Line 181
	at C:\git\godot\platform\windows\godot_windows.cpp(181)
app.exe!_main() Line 206
	at C:\git\godot\platform\windows\godot_windows.cpp(206)
app.exe!main(int argc, char * * argv) Line 220
	at C:\git\godot\platform\windows\godot_windows.cpp(220)
app.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 234
	at C:\git\godot\platform\windows\godot_windows.cpp(234)
[Inline Frame] app.exe!invoke_main() Line 102
	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(102)
app.exe!__scrt_common_main_seh() Line 288
	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()

@rune-scape
Copy link
Contributor

rune-scape commented May 16, 2024

it seems like this is caused by GDScript::reload() failing compilation of a dependant script here:

return GDScriptCache::finish_compiling(main_script->path);

and returning an error code, but the script is still valid,, and then returns:
GDScriptCompiler compiler;
err = compiler.compile(&parser, this, p_keep_state);
if (err) {
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
if (can_run) {
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
}
reloading = false;
return ERR_COMPILATION_FAILED;
} else {
reloading = false;
return err;
}
}

before it initializes the static vars:
if (can_run) {
err = _static_init();
if (err) {
return err;
}
}

then a method is called on an script that should be invalid,, and it segfaults
if valid was set to true in the proper place, and GDScript::callp() checked if the script was valid before calling:
Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *top = this;
while (top) {
HashMap<StringName, GDScriptFunction *>::Iterator E = top->member_functions.find(p_method);
if (E) {
ERR_FAIL_COND_V_MSG(!E->value->is_static(), Variant(), "Can't call non-static function '" + String(p_method) + "' in script.");
return E->value->call(nullptr, p_args, p_argcount, r_error);
}
top = top->_base;
}
//none found, regular
return Script::callp(p_method, p_args, p_argcount, r_error);
}

that should fix this, and it does, im making a PR :)
(i do not know why #90601 brought this out but it doesnt seem to have anything to do with it directly)
(Edit: #90601 made the cache resolve dependant parsers as a part of fully resolving a script and that might have brought out this other bug)

@github-project-automation github-project-automation bot moved this to For team assessment in GDScript Issue Triage May 17, 2024
@vnen vnen moved this from For team assessment to Fix pending review in GDScript Issue Triage May 17, 2024
@akien-mga akien-mga moved this from Release Blocker to Immediate Blocker in 4.x Release Blockers May 17, 2024
@adamscott
Copy link
Member

@rune-scape Thanks for your quick assessment!

@github-project-automation github-project-automation bot moved this from Fix pending review to Done in GDScript Issue Triage May 19, 2024
@hsandt
Copy link
Contributor

hsandt commented May 27, 2024

Hey, I'm testing latest Godot build (v4.3.beta.custom_build [be56cab]) in order to see if this would fix projects using addon "Dialogic" (see issue mentioning this one just above - but in the meantime I tried this issue's MWE and it also uses Dialogic, so it should be the same cause).

Since the Export Template Manager says "Download from: (no templates for developments builds)", and I can only download up to the 4.3.dev6 export template from the website, I had to duplicate 4.3.dev6 template folder ~/.local/share/godot/export_templates/4.3.dev6 to 4.3.beta (and also change version.txt content to 4.3.beta), then that Godot custom build allowed exporting to Linux.

Then I ran both the MWE provided in this issue and 2 of my own MWE:

  • MWE from issue: crashes on start with errors like:

ERROR: Parser bug: Mismatched external parser.
at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:920)

ERROR: File 'res://test-scenes/Main.tscn' can't be loaded, as it uses a format version (6) or engine version (4.3) which are not supported by your engine version (4.3).

  • MWE created directly with my Godot bleeding edge: crash on start with similar errors

=> looks like duplicating that template was not clean, I need to know how to test export template for Godot dev build properly

  • MWE created with Godot 4.2.1 then reopened with my Godot bleeding edge: crash on start with same errors as in 4.2.1, before the fix:

ERROR: Failed to load script "res://addons/dialogic/Resources/CharacterResourceLoader.gd" with error "Compilation failed".

So, are we certain that the fix actually fixed the issue for Dialogic? And how can I test it properly with export templates on latest Godot, if it doesn't have dedicated export templates?

@Ebbo
Copy link
Author

Ebbo commented May 27, 2024

Hi thanks for testing again. I would ask you to also build the templates for your commit you try to test.
To do so run:
scons platform=linuxbsd target=template_release arch=x86_64
scons platform=linuxbsd target=template_debug arch=x86_64
I already tested that and can confirm that the segfault is gone - but would be great to double check.

Please also have a look at: #92337
This might be also related to create a 'working export' with dialogic right now.

@Calinou
Copy link
Member

Calinou commented May 27, 2024

=> looks like duplicating that template was not clean, I need to know how to test export template for Godot dev build properly

You need to compile export templates from source to test, as export templates are not guaranteed to be compatible across different dev builds.

@hsandt
Copy link
Contributor

hsandt commented May 27, 2024

Hi thanks for testing again. I would ask you to also build the templates for your commit you try to test. To do so run: scons platform=linuxbsd target=template_release arch=x86_64 scons platform=linuxbsd target=template_debug arch=x86_64 I already tested that and can confirm that the segfault is gone - but would be great to double check.

Please also have a look at: #92337 This might be also related to create a 'working export' with dialogic right now.

Thanks, in the meantime the plugin dev told me to update to their Alpha 14 and it fixed this particular issue even on Godot 4.2.1, so it was apparently unrelated to this Godot issue. For 92337 (custom ResourceLoader not registered) I'm not sure how they fixed it on plugin side, maybe it's not totally fixed on editor side and that would explain some tool errors, but I see no errors at runtime anymore in the terminal.

Anyway, it's still good to know how to build templates for later. I remember it was written on the build doc page now.

@coppolaemilio coppolaemilio reopened this May 31, 2024
@coppolaemilio
Copy link
Member

Reopening the issue. While it is not automatically crashing any more, the project still doesn't run. So it seems like it is not resolved yet.

@coppolaemilio
Copy link
Member

When running the repro project you should see a basic dialog, but with the latest build, you only see a gray screen.

The errors are:


Godot Engine v4.3.beta1.official.a4f2ea91a - https://godotengine.org
Vulkan 1.2.275 - Forward+ - Using Device #0: Apple - Apple M1 Pro

2024-05-31 16:17:34.570 New Game Project[40780:1285077] WARNING: AVCaptureDeviceTypeExternal is deprecated for Continuity Cameras. Please use AVCaptureDeviceTypeContinuityCamera and add NSCameraUseContinuityCameraDeviceType to your Info.plist.
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
SCRIPT ERROR: Parse Error: Cannot infer the type of "_result" variable because the value doesn't have a set type.
          at: GDScript::reload (res://addons/dialogic/Modules/History/subsystem_history.gd:68)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Text/auto_skip.gd:-1)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Voice/event_voice.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Voice/subsystem_voice.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Text/auto_advance.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Text/subsystem_text.gd:-1)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
SCRIPT ERROR: Parse Error: Cannot infer the type of "_result" variable because the value doesn't have a set type.
          at: GDScript::reload (res://addons/dialogic/Modules/History/subsystem_history.gd:68)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Choice/subsystem_choices.gd:-1)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
SCRIPT ERROR: Parse Error: Cannot infer the type of "_result" variable because the value doesn't have a set type.
          at: GDScript::reload (res://addons/dialogic/Modules/History/subsystem_history.gd:68)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Modules/Text/event_text.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Core/DialogicResourceUtil.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Resources/timeline.gd:-1)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
ERROR: Parser bug: Mismatched external parser.
   at: resolve_class_member (modules/gdscript/gdscript_analyzer.cpp:909)
SCRIPT ERROR: Parse Error: Cannot infer the type of "_result" variable because the value doesn't have a set type.
          at: GDScript::reload (res://addons/dialogic/Modules/History/subsystem_history.gd:68)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Core/DialogicGameHandler.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Core/DialogicUtil.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Resources/character.gd:-1)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://addons/dialogic/Resources/CharacterResourceLoader.gd:-1)
ERROR: Failed to load script "res://addons/dialogic/Resources/CharacterResourceLoader.gd" with error "Compilation failed".
   at: load (modules/gdscript/gdscript.cpp:2943)
SCRIPT ERROR: Invalid call. Nonexistent function 'start' in base 'Node'.
          at: _ready (res://test-scenes/main.gd:6)
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
     at: cleanup (core/object/object.cpp:2316)
ERROR: 16 resources still in use at exit (run with --verbose for details).
   at: clear (core/io/resource.cpp:604)
./testaa.command: line 15: 40780 Segmentation fault: 11  "$BASE_PATH/testaa.app/Contents/MacOS/New Game Project" "$@"

It also crashes when closing the project (also noticed that the editor does the same, so not sure if related with this project or not)

@Ebbo
Copy link
Author

Ebbo commented May 31, 2024

@coppolaemilio thanks for taking a second look - what you describe here is mentionend in: #92337 there is also a workaround where i got the dialog working.

@coppolaemilio
Copy link
Member

There shouldn't be a need to change any setting like this from version to version when running from the editor works but not in its exported version, so I think this issue is still unresolved

@dalexeev dalexeev moved this from Done to Up for grabs in GDScript Issue Triage Jun 4, 2024
@freehuntx
Copy link

Can confirm this also happens for me 😘

@DanielSnd
Copy link
Contributor

Interesting, I ran into that same error, and perhaps the same issue, I wrote about it here. I thought it would be related to the cyclic reference issue:
#78074 (comment)

I could not create an MRP of it though. I managed to get a work around. I'm also getting that error in the editor itself but not sure if it's the same cause or a different cause.

@akien-mga akien-mga changed the title Godot 4.3 Pull Request 90601 broke addon compatibility and segfaults GDScript PR #90601 broke addon compatibility and segfaults Jun 11, 2024
@github-project-automation github-project-automation bot moved this from Up for grabs to Done in GDScript Issue Triage Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Immediate Blocker
Archived in project
9 participants