Skip to content

When using Godot Tools, Godot Editor crashes in parse_statement #1007

Description

@Goldenlion5648

Godot version

4.7 dev4

VS Code version

1.110.1

Godot Tools VS Code extension version

2.6.1

System information

Linux x64 6.19.6-arch1-1

Issue description

I had this code

func _ready() -> void:
	# some random code spanning 25 lines here

	LimboConsole.register_command(func():
		toggle_hot_reload()
		LimboConsole.info("hot reload is now " + str(is_hot_reload_level_content_enabled))	
	)

then I inserted a comma at the end of the LimboConsole.info line, and pressed enter, and saved. The result looked like

func _ready() -> void:
	# some random code spanning 25 lines here

	LimboConsole.register_command(func():
		toggle_hot_reload()
		LimboConsole.info("hot reload is now " + str(is_hot_reload_level_content_enabled)),  # here
                                                                                              # new line, then ctrl + s caused crash
	)

This resulted in this stack trace, showing that current_function was null (so current_function->min_local_doc_line is no good)
https://github.com/godotengine/godot/blob/755fa449c4/modules/gdscript/gdscript_parser.cpp#L2227-L2232

stack trace:

GDScriptParser::parse_statement() (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:2232)
GDScriptParser::parse_suite(String const&, GDScriptParser::SuiteNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:1983)
GDScriptParser::parse_function(bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:1839)
void GDScriptParser::parse_class_member<GDScriptParser::FunctionNode>(GDScriptParser::FunctionNode* (GDScriptParser::*)(bool), GDScriptParser::AnnotationInfo::TargetKind, String const&, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:1076)
GDScriptParser::parse_class_body(bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:1149)
GDScriptParser::parse_program() (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:848)
GDScriptParser::parse(String const&, String const&, bool, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_parser.cpp:520)
GDScriptParserRef::raise_status(GDScriptParserRef::Status) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_cache.cpp:91)
GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:4571)
GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:4775)
GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:2653)
GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode*, bool, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:3585)
GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:2626)
GDScriptAnalyzer::resolve_node(GDScriptParser::Node*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:1659)
GDScriptAnalyzer::resolve_suite(GDScriptParser::SuiteNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:2067)
GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:2016)
GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode*, GDScriptParser::Node const*) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:1430)
GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode*, bool) (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:1574)
GDScriptAnalyzer::resolve_body() (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:6593)
GDScriptAnalyzer::analyze() (/home/golden/Documents/programming/prs/godot/modules/gdscript/gdscript_analyzer.cpp:6623)
ExtendGDScriptParser::parse(String const&, String const&) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_extend_parser.cpp:1025)
GDScriptLanguageProtocol::LSPeer::parse_script(String const&) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_language_protocol.cpp:431)
GDScriptLanguageProtocol::lsp_did_change(Dictionary const&) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_language_protocol.cpp:518)
GDScriptTextDocument::didChange(Variant const&) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_text_document.cpp:76)
void call_with_variant_args_helper<GDScriptTextDocument, Variant const&, 0ul>(GDScriptTextDocument*, void (GDScriptTextDocument::*)(Variant const&), Variant const**, Callable::CallError&, IndexSequence<0ul>) (/home/golden/Documents/programming/prs/godot/core/variant/binder_common.h:59)
void call_with_variant_args<GDScriptTextDocument, Variant const&>(GDScriptTextDocument*, void (GDScriptTextDocument::*)(Variant const&), Variant const**, int, Callable::CallError&) (/home/golden/Documents/programming/prs/godot/core/variant/binder_common.h:173)
CallableCustomMethodPointer<GDScriptTextDocument, void, Variant const&>::call(Variant const**, int, Variant&, Callable::CallError&) const (/home/golden/Documents/programming/prs/godot/core/object/callable_mp.h:103)
Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (/home/golden/Documents/programming/prs/godot/core/variant/callable.cpp:58)
Callable::callv(Array const&) const (/home/golden/Documents/programming/prs/godot/core/variant/callable.cpp:85)
JSONRPC::process_action(Variant const&, bool) (/home/golden/Documents/programming/prs/godot/modules/jsonrpc/jsonrpc.cpp:129)
JSONRPC::process_string(String const&) (/home/golden/Documents/programming/prs/godot/modules/jsonrpc/jsonrpc.cpp:173)
GDScriptLanguageProtocol::process_message(String const&) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_language_protocol.cpp:162)
GDScriptLanguageProtocol::LSPeer::handle_data() (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_language_protocol.cpp:113)
GDScriptLanguageProtocol::poll(int) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_language_protocol.cpp:321)
GDScriptLanguageServer::thread_main(void*) (/home/golden/Documents/programming/prs/godot/modules/gdscript/language_server/gdscript_language_server.cpp:85)
Thread::callback(unsigned long, Thread::Settings const&, void (*)(void*), void*) (/home/golden/Documents/programming/prs/godot/core/os/thread.cpp:64)
void std::__invoke_impl<void, void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>(std::__invoke_other, void (*&&)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long&&, Thread::Settings&&, void (*&&)(void*), void*&&) (/usr/include/c++/15.2.1/bits/invoke.h:63)
std::__invoke_result<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>::type std::__invoke<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>(void (*&&)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long&&, Thread::Settings&&, void (*&&)(void*), void*&&) (/usr/include/c++/15.2.1/bits/invoke.h:98)
void std::thread::_Invoker<std::tuple<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>>::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul>) (/usr/include/c++/15.2.1/bits/std_thread.h:303)
std::thread::_Invoker<std::tuple<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>>::operator()() (/usr/include/c++/15.2.1/bits/std_thread.h:310)
std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>>>::_M_run() (/usr/include/c++/15.2.1/bits/std_thread.h:255)
execute_native_thread_routine (Unknown Source:0)
___lldb_unnamed_symbol_96680 (Unknown Source:0)
___lldb_unnamed_symbol_11a2b5 (Unknown Source:0)

Steps to reproduce

Seems like there might be a race condition, so it is possible the size of the file has an effect. In My case the ready function was on about line 300, with the entire .gd file size being 1200 lines.

  1. Make sure the game is running (with Godot's built in hot-reload running)
  2. Have the script file with the above snippet open in both VSCode and the Godot Script editor

Seems like passing a function, followed by a comma and new line causes this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions