blob: a41bdd36e5fefe0e3db610665a8745627804b587 [file] [log] [blame]
//===-- LaunchRequestHandler.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DAP.h"
#include "EventHelper.h"
#include "JSONUtils.h"
#include "RequestHandler.h"
#include "llvm/Support/FileSystem.h"
namespace lldb_dap {
// "LaunchRequest": {
// "allOf": [ { "$ref": "#/definitions/Request" }, {
// "type": "object",
// "description": "Launch request; value of command field is 'launch'.",
// "properties": {
// "command": {
// "type": "string",
// "enum": [ "launch" ]
// },
// "arguments": {
// "$ref": "#/definitions/LaunchRequestArguments"
// }
// },
// "required": [ "command", "arguments" ]
// }]
// },
// "LaunchRequestArguments": {
// "type": "object",
// "description": "Arguments for 'launch' request.",
// "properties": {
// "noDebug": {
// "type": "boolean",
// "description": "If noDebug is true the launch request should launch
// the program without enabling debugging."
// }
// }
// },
// "LaunchResponse": {
// "allOf": [ { "$ref": "#/definitions/Response" }, {
// "type": "object",
// "description": "Response to 'launch' request. This is just an
// acknowledgement, so no body field is required."
// }]
// }
void LaunchRequestHandler::operator()(const llvm::json::Object &request) const {
dap.is_attach = false;
dap.last_launch_or_attach_request = request;
llvm::json::Object response;
FillResponse(request, response);
const auto *arguments = request.getObject("arguments");
dap.init_commands = GetStrings(arguments, "initCommands");
dap.pre_run_commands = GetStrings(arguments, "preRunCommands");
dap.stop_commands = GetStrings(arguments, "stopCommands");
dap.exit_commands = GetStrings(arguments, "exitCommands");
dap.terminate_commands = GetStrings(arguments, "terminateCommands");
dap.post_run_commands = GetStrings(arguments, "postRunCommands");
dap.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
dap.enable_auto_variable_summaries =
GetBoolean(arguments, "enableAutoVariableSummaries", false);
dap.enable_synthetic_child_debugging =
GetBoolean(arguments, "enableSyntheticChildDebugging", false);
dap.display_extended_backtrace =
GetBoolean(arguments, "displayExtendedBacktrace", false);
dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`");
dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
dap.SetThreadFormat(GetString(arguments, "customThreadFormat"));
PrintWelcomeMessage();
// This is a hack for loading DWARF in .o files on Mac where the .o files
// in the debug map of the main executable have relative paths which
// require the lldb-dap binary to have its working directory set to that
// relative root for the .o files in order to be able to load debug info.
if (!debuggerRoot.empty())
llvm::sys::fs::set_current_path(debuggerRoot);
// Run any initialize LLDB commands the user specified in the launch.json.
// This is run before target is created, so commands can't do anything with
// the targets - preRunCommands are run with the target.
if (llvm::Error err = dap.RunInitCommands()) {
response["success"] = false;
EmplaceSafeString(response, "message", llvm::toString(std::move(err)));
dap.SendJSON(llvm::json::Value(std::move(response)));
return;
}
SetSourceMapFromArguments(*arguments);
lldb::SBError status;
dap.SetTarget(dap.CreateTargetFromArguments(*arguments, status));
if (status.Fail()) {
response["success"] = llvm::json::Value(false);
EmplaceSafeString(response, "message", status.GetCString());
dap.SendJSON(llvm::json::Value(std::move(response)));
return;
}
// Run any pre run LLDB commands the user specified in the launch.json
if (llvm::Error err = dap.RunPreRunCommands()) {
response["success"] = false;
EmplaceSafeString(response, "message", llvm::toString(std::move(err)));
dap.SendJSON(llvm::json::Value(std::move(response)));
return;
}
status = LaunchProcess(request);
if (status.Fail()) {
response["success"] = llvm::json::Value(false);
EmplaceSafeString(response, "message", std::string(status.GetCString()));
} else {
dap.RunPostRunCommands();
}
dap.SendJSON(llvm::json::Value(std::move(response)));
if (!status.Fail()) {
if (dap.is_attach)
SendProcessEvent(dap, Attach); // this happens when doing runInTerminal
else
SendProcessEvent(dap, Launch);
}
dap.SendJSON(CreateEventObject("initialized"));
}
} // namespace lldb_dap