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..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,20 +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. - self._flush_breakpoints() + # 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) 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)