瀏覽代碼

Merge pull request #84895 from rsubtil/fix_dap_race_condition

Prevent race condition on initial breakpoints from DAP
Rémi Verschelde 1 年之前
父節點
當前提交
4baa634937

+ 19 - 2
editor/debugger/debug_adapter/debug_adapter_parser.cpp

@@ -44,7 +44,7 @@ void DebugAdapterParser::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("req_attach", "params"), &DebugAdapterParser::req_attach);
 	ClassDB::bind_method(D_METHOD("req_restart", "params"), &DebugAdapterParser::req_restart);
 	ClassDB::bind_method(D_METHOD("req_terminate", "params"), &DebugAdapterParser::req_terminate);
-	ClassDB::bind_method(D_METHOD("req_configurationDone", "params"), &DebugAdapterParser::prepare_success_response);
+	ClassDB::bind_method(D_METHOD("req_configurationDone", "params"), &DebugAdapterParser::req_configurationDone);
 	ClassDB::bind_method(D_METHOD("req_pause", "params"), &DebugAdapterParser::req_pause);
 	ClassDB::bind_method(D_METHOD("req_continue", "params"), &DebugAdapterParser::req_continue);
 	ClassDB::bind_method(D_METHOD("req_threads", "params"), &DebugAdapterParser::req_threads);
@@ -180,6 +180,13 @@ Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) const {
 		DebugAdapterProtocol::get_singleton()->get_current_peer()->supportsCustomData = args["godot/custom_data"];
 	}
 
+	DebugAdapterProtocol::get_singleton()->get_current_peer()->pending_launch = p_params;
+
+	return Dictionary();
+}
+
+Dictionary DebugAdapterParser::_launch_process(const Dictionary &p_params) const {
+	Dictionary args = p_params["arguments"];
 	ScriptEditorDebugger *dbg = EditorDebuggerNode::get_singleton()->get_default_debugger();
 	if ((bool)args["noDebug"] != dbg->is_skip_breakpoints()) {
 		dbg->debug_skip_breakpoints();
@@ -246,7 +253,7 @@ Dictionary DebugAdapterParser::req_restart(const Dictionary &p_params) const {
 	args = args["arguments"];
 	params["arguments"] = args;
 
-	Dictionary response = DebugAdapterProtocol::get_singleton()->get_current_peer()->attached ? req_attach(params) : req_launch(params);
+	Dictionary response = DebugAdapterProtocol::get_singleton()->get_current_peer()->attached ? req_attach(params) : _launch_process(params);
 	if (!response["success"]) {
 		response["command"] = p_params["command"];
 		return response;
@@ -261,6 +268,16 @@ Dictionary DebugAdapterParser::req_terminate(const Dictionary &p_params) const {
 	return prepare_success_response(p_params);
 }
 
+Dictionary DebugAdapterParser::req_configurationDone(const Dictionary &p_params) const {
+	Ref<DAPeer> peer = DebugAdapterProtocol::get_singleton()->get_current_peer();
+	if (!peer->pending_launch.is_empty()) {
+		peer->res_queue.push_back(_launch_process(peer->pending_launch));
+		peer->pending_launch.clear();
+	}
+
+	return prepare_success_response(p_params);
+}
+
 Dictionary DebugAdapterParser::req_pause(const Dictionary &p_params) const {
 	EditorRunBar::get_singleton()->get_pause_button()->set_pressed(true);
 	EditorDebuggerNode::get_singleton()->_paused();

+ 4 - 0
editor/debugger/debug_adapter/debug_adapter_parser.h

@@ -71,6 +71,7 @@ public:
 	Dictionary req_attach(const Dictionary &p_params) const;
 	Dictionary req_restart(const Dictionary &p_params) const;
 	Dictionary req_terminate(const Dictionary &p_params) const;
+	Dictionary req_configurationDone(const Dictionary &p_params) const;
 	Dictionary req_pause(const Dictionary &p_params) const;
 	Dictionary req_continue(const Dictionary &p_params) const;
 	Dictionary req_threads(const Dictionary &p_params) const;
@@ -84,6 +85,9 @@ public:
 	Dictionary req_evaluate(const Dictionary &p_params) const;
 	Dictionary req_godot_put_msg(const Dictionary &p_params) const;
 
+	// Internal requests
+	Dictionary _launch_process(const Dictionary &p_params) const;
+
 	// Events
 	Dictionary ev_initialized() const;
 	Dictionary ev_process(const String &p_command) const;

+ 4 - 1
editor/debugger/debug_adapter/debug_adapter_protocol.cpp

@@ -678,7 +678,10 @@ bool DebugAdapterProtocol::process_message(const String &p_text) {
 		if (!response.is_empty()) {
 			_current_peer->res_queue.push_front(response);
 		} else {
-			completed = false;
+			// Launch request needs to be deferred until we receive a configurationDone request.
+			if (command != "req_launch") {
+				completed = false;
+			}
 		}
 	}
 

+ 1 - 0
editor/debugger/debug_adapter/debug_adapter_protocol.h

@@ -63,6 +63,7 @@ struct DAPeer : RefCounted {
 
 	// Internal client info
 	bool attached = false;
+	Dictionary pending_launch;
 
 	Error handle_data();
 	Error send_data();