| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/debug/zxdb/debug_adapter/handlers/request_launch.h" |
| |
| #include <dap/types.h> |
| |
| #include "src/developer/debug/shared/message_loop.h" |
| #include "src/developer/debug/zxdb/client/filter.h" |
| #include "src/developer/debug/zxdb/client/session.h" |
| |
| namespace dap { |
| |
| DAP_IMPLEMENT_STRUCT_TYPEINFO_EXT(LaunchRequestZxdb, LaunchRequest, "launch", |
| DAP_FIELD(process, "process"), |
| DAP_FIELD(launchCommand, "launchCommand"), DAP_FIELD(cwd, "cwd")) |
| |
| } // namespace dap |
| |
| namespace zxdb { |
| |
| void GetCommandArray(const dap::string& cmd_string, dap::array<dap::string>& cmd) { |
| // Split command string at whitespaces to an array of strings. |
| // This is required by RunInTerminal request. |
| size_t split_pos = cmd_string.find(' '); |
| size_t start_pos = 0; |
| |
| while (split_pos != std::string::npos) { |
| cmd.push_back(cmd_string.substr(start_pos, split_pos - start_pos)); |
| start_pos = split_pos + 1; |
| split_pos = cmd_string.find(' ', start_pos); |
| } |
| |
| cmd.push_back( |
| cmd_string.substr(start_pos, std::min(split_pos, cmd_string.size()) - start_pos + 1)); |
| } |
| |
| dap::ResponseOrError<dap::LaunchResponse> OnRequestLaunch(DebugAdapterContext* context, |
| const dap::LaunchRequestZxdb& req) { |
| if (!context->supports_run_in_terminal()) { |
| return dap::Error( |
| "Client doesn't support run in terminal. Please launch program manually and use attach " |
| "instead of launch to connect to zxdb."); |
| } |
| |
| Filter* filter = context->session()->system().CreateNewFilter(); |
| filter->SetPattern(req.process); |
| |
| dap::RunInTerminalRequest run_request; |
| run_request.title = "zxdb launch"; |
| run_request.kind = "integrated"; |
| GetCommandArray(req.launchCommand, run_request.args); |
| if (req.cwd) { |
| run_request.cwd = req.cwd.value(); |
| } |
| // Send RunInTerminal request. |
| // TODO(69387): Currently not waiting for the response from the client. Because the |
| // response is returned as a future and waiting on it will block the MessageLoop creating a |
| // deadlock, as MessageLoop should be running in order to receive the response. This can be fixed |
| // by getting a response notification from cppdap. |
| // Secondly, the response contains launched terminal process ID, but nothing about whether the |
| // command ran successfully. It might be helpful to return error to Launch request after getting |
| // error code(if any exists) from launched process. |
| context->dap().send(run_request); |
| |
| return dap::LaunchResponse(); |
| } |
| |
| } // namespace zxdb |