-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Implemented initial DAP support #50454
Conversation
I also have the original unsquashed commit history here, if it's helpful for reviewing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good! 👀 🥇
See the comments about containment and signals name, beside that, I'll do some testing once I manage to properly setup VS Code 😕 .
breaked = true; | ||
can_debug = can_continue; | ||
_update_buttons_state(); | ||
_set_reason_text(error, MESSAGE_ERROR); | ||
emit_signal("breaked", true, can_continue); | ||
DisplayServer::get_singleton()->window_move_to_foreground(); | ||
emit_signal("dap:breaked", error, has_stackdump); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that instead of adding dap:
prefixed signals, we should just update the current ones, and add any extra needed one as non-prefixed.
The debuggers are exposed to Godot Editor plugins, so they'll benefit from this too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
breaked = true; | ||
can_debug = can_continue; | ||
_update_buttons_state(); | ||
_set_reason_text(error, MESSAGE_ERROR); | ||
emit_signal("breaked", true, can_continue); | ||
DisplayServer::get_singleton()->window_move_to_foreground(); | ||
emit_signal("dap:breaked", error, has_stackdump); | ||
if (!DebugAdapterProtocol::get_singleton()->is_active()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For self-containment I would rather add this as a variable move_to_foreground
that can be set via:
EditorDebuggerNode::get_singleton()->get_default_debugger()->set_move_to_foreground(false);
when the debugger is started by the DebugAdapterProtocol
(and reset internally when the debugger disconnects).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
editor/editor_node.cpp
Outdated
@@ -2284,7 +2285,12 @@ void EditorNode::_run(bool p_current, const String &p_custom) { | |||
editor_data.get_editor_breakpoints(&breakpoints); | |||
|
|||
args = ProjectSettings::get_singleton()->get("editor/run/main_run_args"); | |||
skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints(); | |||
DebugAdapterProtocol *dap = DebugAdapterProtocol::get_singleton(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, it took me a bit to realize this, but as suggested for the move_to_foreground
option, we can use the internal is_skip_breakpoints
directly.
Instead of looking for the DAP current args, have the DebugAdapterProtocol
call:
ScriptEditorDebugger *dbg = EditorDebuggerNode::get_singleton()->get_default_debugger();
if (arg["noDebug"] != dbg->is_skip_breakpoints()) {
dbg->debug_skip_breakpoints();
}
Before emitting "play".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed; also removed the current_args
from DebugAdapterProtocol
, as it's not needed anymore
94d5c9c
to
cb9e3fb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment about path checking.
This is excellent work 🥇 , and also tested a bit in VS Code.
I think is is good to merge as a first iteration 🟢
|
||
Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) { | ||
Dictionary args = p_params["arguments"]; | ||
if (args.has("project") && !is_valid_path(args["project"])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This caused me troubles due to symbolic link (I opened VSCode in the symlinked folder, while Godot used the real path).
I think this is an edge case that we might have to deal at some point, but it's not super important in common workflows. A better error, telling you the received (if any) and the expected path, would have saved me some debugging 😅 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized the error was being incorrectly sent, so VSCode didn't show the full message. I've fixed it now, and I've also updated that one to show both paths like you suggested.
Since the default DAP port is 6009, isn't that going to be an issue with the editor remote debugger attempting ports 6007, then 6008, then 6009, and so on? The automatic remote debugger port assignment was implemented in #37067. It hasn't been forward-ported to |
@Calinou yup, that's a problem. I can change it to something lower like But LSP uses 6008, so that's an issue too 😕 |
It's the same as with the LSP (port 6008). It will fail 2 times (instead of 1 like it does now). Btw, weren't they both supposed to be behind a flag? Seems like they are auto-started on editor start, which sounds like a security issue. |
If the servers only listen on |
Right 👍 , we should probably make that an option, and use 127.0.0.1 by default (like we do for the web server).
Yeah, I guess that's the best choice. We can change the LSP default port in another PR. |
This comment has been minimized.
This comment has been minimized.
Implemented "output" event Refactored "seq" field generation Prevent debugging when editor and client are in different projects Removed unneeded references to peer on the parser Refactored way to detect project path Implemented "setBreakpoints" request Fix double events when terminating from client Refactored "stopped" event Implemented "stopped" with breakpoint event Implemented "stackTrace", "scopes" and "variables" request Report incoming number of stack dump variables Implemented proper reporting of scopes and variables from stack frames Prevent editor from grabbing focus when a DAP session is active Implemented "next" and "stepIn" requests Implemented "Source" checksum computing Switched expected errors from macros to silent guards Refactored message_id Respect client settings regarding lines/columns behavior Refactored nested DAP fields Implement reporting of "Members" and "Globals" scopes as well Fix error messages not being shown, and improved wrong path message
Changed the port to @shackra since Nathan mentioned they've "sponsored someone to fix these issues", I don't want to potentially step into someone's current work. However, if there's indeed no active development on that, I don't mind having a look and see where I can help, in a few weeks. |
@Razoric480 has been doing a number of fixes for the LSP, at least in part on behalf of GDQuest. So the issues referenced in this older issue might be solved. If not, they would be best described in dedicated bug reports so that @Razoric480 (and possibly @ev1lbl0w which his DAP expertise) could have a look at them. We're getting close to having a "External editors" team :) |
@ev1lbl0w @akien-mga I am not working on any specific LSP issue at the moment. Occasionally I see something wrong or that I want to improve and so work on it. That said, I don't recognize any of those issues as linked by @shackra and my testbed is in VSCode. I am not an emac user (and in fact it frightens me) so I'm not sure what could be wrong. By the way, nice work on the DAP. My initial implementation of the debugger extension in vscode was based off the TCP/IP protocol godot uses, so its quality, while it worked, felt a bit cobbled together in places. |
Really nice work! Thanks! 🎊 🏆 |
(for GSoC DAP project, and godot-proposals#2494)
This PR implements support for the debug adapter protocol (DAP), implementing the most essential commands:
initialize/disconnect
for protocol (de)initializationlaunch/terminate
for launching and terminating debug instancespause/continue
for pausing and continuingnext/stepIn
for stepping over and insetBreakpoints
for setting breakpointsstackTrace/scopes/variables
for stacktrace information and variables...
(other small miscellaneous requests implemented, the complete list can be quickly checked atDebugAdapterParser.cpp:_bind_methods()
)DebugAdapterProtocol
andDebugAdapterParser
work in tandem to implement the protocol backend: whileProtocol
handles communication, translating debugging info, notifying client and connects to various signals from the editor,Parser
is focused with building the response packets for each request/event that is needed, and changing editor state in response to requests.Other changes that were made:
Added new editor settings into a "Debug Adapter" category, similarly to how LSP is implemented. The default port for DAP is
6009
.Changed some communication messages between editor and project (
core/debugger/remote_debugger.cpp
):debug_enter
now has an additional boolean field, indicating if the debugee has any stack frames to send. This allows to know immediately whether stackframes are coming or not, which is needed to distinguish between a breakpoint and a pause command.stack_frame_vars
now reports the amount of variables it will be sending, allowing for the protocol to properly wait until all variables have been received.Added a few signals on
editor/debugger/script_editor_debugger.cpp
to send information nedded for the protocol. These are prefixed withdap:
as they're tailored for the protocol (except the newoutput
signal)I've done all testing under VSCode, and I'm able to already debug projects normally without ever touching the editor 🙂. Other from that, I've inspected the packets through Wireshark and manually check if they're correct according to the specification. However, this definitely needs more testing under other text editors/IDEs.