From 50d7cda0f78cc62507cd00666323a902bcd69306 Mon Sep 17 00:00:00 2001 From: Janet Yang Date: Wed, 26 Nov 2025 15:12:23 -0800 Subject: [PATCH 1/2] [lldb-dap] Add breakpoints after debugger initialization --- .../debuginfo-tests/dexter/dex/debugger/DAP.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py index 792e0be629fc4..0ea0674ea5898 100644 --- a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py +++ b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py @@ -765,12 +765,14 @@ def launch(self, cmdline): # For some reason, we *must* submit in the order launch->configurationDone, and then we will receive responses # in the order configurationDone->launch. - self._flush_breakpoints() launch_req_id = self.send_message(self.make_request("launch", launch_request)) config_done_req_id = self.send_message(self.make_request("configurationDone")) config_done_response = self._await_response(config_done_req_id) assert config_done_response["success"], "Should simply receive an affirmative?" launch_response = self._await_response(launch_req_id) + + # Flush breakpoints after launch completes, as the debugger is now available. + self._flush_breakpoints() if not launch_response["success"]: raise DebuggerException( f"failure launching debugger: \"{launch_response['body']['error']['format']}\"" From 37d39a901883965c0a4f0cb8a7eb896c97f34c9f Mon Sep 17 00:00:00 2001 From: Janet Yang Date: Wed, 26 Nov 2025 16:37:51 -0800 Subject: [PATCH 2/2] Send configurationDone --- .../dexter/dex/debugger/DAP.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py index 0ea0674ea5898..68ca50a5e81db 100644 --- a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py +++ b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py @@ -763,22 +763,27 @@ def launch(self, cmdline): launch_request = self._get_launch_params(cmdline) - # For some reason, we *must* submit in the order launch->configurationDone, and then we will receive responses - # in the order configurationDone->launch. + # Per DAP protocol, the correct sequence is: + # 1. Send launch request + # 2. Wait for launch response and "initialized" event + # 3. Set breakpoints + # 4. Send configurationDone to start the process launch_req_id = self.send_message(self.make_request("launch", launch_request)) - config_done_req_id = self.send_message(self.make_request("configurationDone")) - config_done_response = self._await_response(config_done_req_id) - assert config_done_response["success"], "Should simply receive an affirmative?" launch_response = self._await_response(launch_req_id) - - # Flush breakpoints after launch completes, as the debugger is now available. - self._flush_breakpoints() if not launch_response["success"]: raise DebuggerException( f"failure launching debugger: \"{launch_response['body']['error']['format']}\"" ) - # We can't interact meaningfully with the process until we have the thread ID and confirmation that the process - # has finished launching. + + # Set breakpoints after receiving launch response but before configurationDone. + self._flush_breakpoints() + + # Send configurationDone to allow the process to start running. + config_done_req_id = self.send_message(self.make_request("configurationDone")) + config_done_response = self._await_response(config_done_req_id) + assert config_done_response["success"] + + # Wait for the process to launch and obtain a thread ID. while self._debugger_state.thread is None or not self._debugger_state.launched: time.sleep(0.001)