godotengine / godotengine/godot-vscode-plugin

When using Godot Tools, Godot Editor crashes in parse_statement

Open
#1,007 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
2.1k
Forks
257
PR merge metrics
No merged PRs in 30d

Description

### 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::*)(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*, 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*, void (GDScriptTextDocument::*)(Variant const&), Variant const**, int, Callable::CallError&) (/home/golden/Documents/programming/prs/godot/core/variant/binder_common.h:173)
CallableCustomMethodPointer::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(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::type std::__invoke(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>::_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>::operator()() (/usr/include/c++/15.2.1/bits/std_thread.h:310)
std::thread::_State_impl>>::_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?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.