Skip to content

[lldb-dap] Creating a common configuration structure for launch and attach requests. #133960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions lldb/tools/lldb-dap/DAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,20 @@ const char DEV_NULL[] = "/dev/null";

namespace lldb_dap {

DAP::DAP(llvm::StringRef path, Log *log, const ReplMode default_repl_mode,
llvm::StringRef DAP::debug_adapter_path = "";

DAP::DAP(Log *log, const ReplMode default_repl_mode,
std::vector<std::string> pre_init_commands, Transport &transport)
: debug_adapter_path(path), log(log), transport(transport),
broadcaster("lldb-dap"), exception_breakpoints(),
pre_init_commands(std::move(pre_init_commands)),
focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false),
enable_auto_variable_summaries(false),
enable_synthetic_child_debugging(false),
display_extended_backtrace(false),
: log(log), transport(transport), broadcaster("lldb-dap"),
exception_breakpoints(), focus_tid(LLDB_INVALID_THREAD_ID),
stop_at_entry(false), is_attach(false),
restarting_process_id(LLDB_INVALID_PROCESS_ID),
configuration_done_sent(false), waiting_for_run_in_terminal(false),
progress_event_reporter(
[&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }),
reverse_request_seq(0), repl_mode(default_repl_mode) {}
reverse_request_seq(0), repl_mode(default_repl_mode) {
configuration.preInitCommands = std::move(pre_init_commands);
}

DAP::~DAP() = default;

Expand Down Expand Up @@ -505,8 +505,9 @@ ReplMode DAP::DetectReplMode(lldb::SBFrame frame, std::string &expression,
bool partial_expression) {
// Check for the escape hatch prefix.
if (!expression.empty() &&
llvm::StringRef(expression).starts_with(command_escape_prefix)) {
expression = expression.substr(command_escape_prefix.size());
llvm::StringRef(expression)
.starts_with(configuration.commandEscapePrefix)) {
expression = expression.substr(configuration.commandEscapePrefix.size());
return ReplMode::Command;
}

Expand Down Expand Up @@ -546,7 +547,7 @@ ReplMode DAP::DetectReplMode(lldb::SBFrame frame, std::string &expression,
<< "Warning: Expression '" << term
<< "' is both an LLDB command and variable. It will be evaluated as "
"a variable. To evaluate the expression as an LLDB command, use '"
<< command_escape_prefix << "' as a prefix.\n";
<< configuration.commandEscapePrefix << "' as a prefix.\n";
}

// Variables take preference to commands in auto, since commands can always
Expand Down Expand Up @@ -593,36 +594,38 @@ DAP::RunLaunchCommands(llvm::ArrayRef<std::string> launch_commands) {
}

llvm::Error DAP::RunInitCommands() {
if (!RunLLDBCommands("Running initCommands:", init_commands))
if (!RunLLDBCommands("Running initCommands:", configuration.initCommands))
return createRunLLDBCommandsErrorMessage("initCommands");
return llvm::Error::success();
}

llvm::Error DAP::RunPreInitCommands() {
if (!RunLLDBCommands("Running preInitCommands:", pre_init_commands))
if (!RunLLDBCommands("Running preInitCommands:",
configuration.preInitCommands))
return createRunLLDBCommandsErrorMessage("preInitCommands");
return llvm::Error::success();
}

llvm::Error DAP::RunPreRunCommands() {
if (!RunLLDBCommands("Running preRunCommands:", pre_run_commands))
if (!RunLLDBCommands("Running preRunCommands:", configuration.preRunCommands))
return createRunLLDBCommandsErrorMessage("preRunCommands");
return llvm::Error::success();
}

void DAP::RunPostRunCommands() {
RunLLDBCommands("Running postRunCommands:", post_run_commands);
RunLLDBCommands("Running postRunCommands:", configuration.postRunCommands);
}
void DAP::RunStopCommands() {
RunLLDBCommands("Running stopCommands:", stop_commands);
RunLLDBCommands("Running stopCommands:", configuration.stopCommands);
}

void DAP::RunExitCommands() {
RunLLDBCommands("Running exitCommands:", exit_commands);
RunLLDBCommands("Running exitCommands:", configuration.exitCommands);
}

void DAP::RunTerminateCommands() {
RunLLDBCommands("Running terminateCommands:", terminate_commands);
RunLLDBCommands("Running terminateCommands:",
configuration.terminateCommands);
}

lldb::SBTarget
Expand Down
23 changes: 7 additions & 16 deletions lldb/tools/lldb-dap/DAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "lldb/API/SBThread.h"
#include "lldb/API/SBValue.h"
#include "lldb/API/SBValueList.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
Expand Down Expand Up @@ -148,12 +147,16 @@ struct SendEventRequestHandler : public lldb::SBCommandPluginInterface {
};

struct DAP {
llvm::StringRef debug_adapter_path;
/// Path to the lldb-dap binary itself.
static llvm::StringRef debug_adapter_path;

Log *log;
Transport &transport;
lldb::SBFile in;
OutputRedirector out;
OutputRedirector err;
/// Configuration specified by the launch or attach commands.
protocol::Configuration configuration;
lldb::SBDebugger debugger;
lldb::SBTarget target;
Variables variables;
Expand All @@ -165,13 +168,6 @@ struct DAP {
InstructionBreakpointMap instruction_breakpoints;
std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
llvm::once_flag init_exception_breakpoints_flag;
std::vector<std::string> pre_init_commands;
std::vector<std::string> init_commands;
std::vector<std::string> pre_run_commands;
std::vector<std::string> post_run_commands;
std::vector<std::string> exit_commands;
std::vector<std::string> stop_commands;
std::vector<std::string> terminate_commands;
// Map step in target id to list of function targets that user can choose.
llvm::DenseMap<lldb::addr_t, std::string> step_in_targets;
// A copy of the last LaunchRequest or AttachRequest so we can reuse its
Expand All @@ -182,9 +178,6 @@ struct DAP {
llvm::once_flag terminated_event_flag;
bool stop_at_entry;
bool is_attach;
bool enable_auto_variable_summaries;
bool enable_synthetic_child_debugging;
bool display_extended_backtrace;
// The process event thread normally responds to process exited events by
// shutting down the entire adapter. When we're restarting, we keep the id of
// the old process here so we can detect this case and keep running.
Expand All @@ -201,7 +194,7 @@ struct DAP {
llvm::SmallDenseMap<int64_t, std::unique_ptr<ResponseHandler>>
inflight_reverse_requests;
ReplMode repl_mode;
std::string command_escape_prefix = "`";

lldb::SBFormat frame_format;
lldb::SBFormat thread_format;
// This is used to allow request_evaluate to handle empty expressions
Expand All @@ -215,8 +208,6 @@ struct DAP {

/// Creates a new DAP sessions.
///
/// \param[in] path
/// Path to the lldb-dap binary.
/// \param[in] log
/// Log stream, if configured.
/// \param[in] default_repl_mode
Expand All @@ -225,7 +216,7 @@ struct DAP {
/// LLDB commands to execute as soon as the debugger instance is allocaed.
/// \param[in] transport
/// Transport for this debug session.
DAP(llvm::StringRef path, Log *log, const ReplMode default_repl_mode,
DAP(Log *log, const ReplMode default_repl_mode,
std::vector<std::string> pre_init_commands, Transport &transport);

~DAP();
Expand Down
21 changes: 11 additions & 10 deletions lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,29 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
attach_info.SetProcessID(pid);
const auto wait_for = GetBoolean(arguments, "waitFor").value_or(false);
attach_info.SetWaitForLaunch(wait_for, false /*async*/);
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.configuration.initCommands = GetStrings(arguments, "initCommands");
dap.configuration.preRunCommands = GetStrings(arguments, "preRunCommands");
dap.configuration.stopCommands = GetStrings(arguments, "stopCommands");
dap.configuration.exitCommands = GetStrings(arguments, "exitCommands");
dap.configuration.terminateCommands =
GetStrings(arguments, "terminateCommands");
auto attachCommands = GetStrings(arguments, "attachCommands");
llvm::StringRef core_file = GetString(arguments, "coreFile").value_or("");
const uint64_t timeout_seconds =
GetInteger<uint64_t>(arguments, "timeout").value_or(30);
dap.stop_at_entry = core_file.empty()
? GetBoolean(arguments, "stopOnEntry").value_or(false)
: true;
dap.post_run_commands = GetStrings(arguments, "postRunCommands");
dap.configuration.postRunCommands = GetStrings(arguments, "postRunCommands");
const llvm::StringRef debuggerRoot =
GetString(arguments, "debuggerRoot").value_or("");
dap.enable_auto_variable_summaries =
dap.configuration.enableAutoVariableSummaries =
GetBoolean(arguments, "enableAutoVariableSummaries").value_or(false);
dap.enable_synthetic_child_debugging =
dap.configuration.enableSyntheticChildDebugging =
GetBoolean(arguments, "enableSyntheticChildDebugging").value_or(false);
dap.display_extended_backtrace =
dap.configuration.displayExtendedBacktrace =
GetBoolean(arguments, "displayExtendedBacktrace").value_or(false);
dap.command_escape_prefix =
dap.configuration.commandEscapePrefix =
GetString(arguments, "commandEscapePrefix").value_or("`");
dap.SetFrameFormat(GetString(arguments, "customFrameFormat").value_or(""));
dap.SetThreadFormat(GetString(arguments, "customThreadFormat").value_or(""));
Expand Down
7 changes: 4 additions & 3 deletions lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,20 @@ void CompletionsRequestHandler::operator()(
llvm::json::Array targets;

bool had_escape_prefix =
llvm::StringRef(text).starts_with(dap.command_escape_prefix);
llvm::StringRef(text).starts_with(dap.configuration.commandEscapePrefix);
ReplMode completion_mode = dap.DetectReplMode(frame, text, true);

// Handle the offset change introduced by stripping out the
// `command_escape_prefix`.
if (had_escape_prefix) {
if (offset < static_cast<int64_t>(dap.command_escape_prefix.size())) {
if (offset <
static_cast<int64_t>(dap.configuration.commandEscapePrefix.size())) {
body.try_emplace("targets", std::move(targets));
response.try_emplace("body", std::move(body));
dap.SendJSON(llvm::json::Value(std::move(response)));
return;
}
offset -= dap.command_escape_prefix.size();
offset -= dap.configuration.commandEscapePrefix.size();
}

// While the user is typing then we likely have an incomplete input and cannot
Expand Down
3 changes: 2 additions & 1 deletion lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ void EvaluateRequestHandler::operator()(
else
EmplaceSafeString(response, "message", "evaluate failed");
} else {
VariableDescription desc(value, dap.enable_auto_variable_summaries);
VariableDescription desc(value,
dap.configuration.enableAutoVariableSummaries);
EmplaceSafeString(body, "result", desc.GetResult(context));
EmplaceSafeString(body, "type", desc.display_type_name);
int64_t var_ref = 0;
Expand Down
21 changes: 11 additions & 10 deletions lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,23 @@ void LaunchRequestHandler::operator()(const llvm::json::Object &request) const {
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.configuration.initCommands = GetStrings(arguments, "initCommands");
dap.configuration.preRunCommands = GetStrings(arguments, "preRunCommands");
dap.configuration.stopCommands = GetStrings(arguments, "stopCommands");
dap.configuration.exitCommands = GetStrings(arguments, "exitCommands");
dap.configuration.terminateCommands =
GetStrings(arguments, "terminateCommands");
dap.configuration.postRunCommands = GetStrings(arguments, "postRunCommands");
dap.stop_at_entry = GetBoolean(arguments, "stopOnEntry").value_or(false);
const llvm::StringRef debuggerRoot =
GetString(arguments, "debuggerRoot").value_or("");
dap.enable_auto_variable_summaries =
dap.configuration.enableAutoVariableSummaries =
GetBoolean(arguments, "enableAutoVariableSummaries").value_or(false);
dap.enable_synthetic_child_debugging =
dap.configuration.enableSyntheticChildDebugging =
GetBoolean(arguments, "enableSyntheticChildDebugging").value_or(false);
dap.display_extended_backtrace =
dap.configuration.displayExtendedBacktrace =
GetBoolean(arguments, "displayExtendedBacktrace").value_or(false);
dap.command_escape_prefix =
dap.configuration.commandEscapePrefix =
GetString(arguments, "commandEscapePrefix").value_or("`");
dap.SetFrameFormat(GetString(arguments, "customFrameFormat").value_or(""));
dap.SetThreadFormat(GetString(arguments, "customThreadFormat").value_or(""));
Expand Down
2 changes: 1 addition & 1 deletion lldb/tools/lldb-dap/Handler/RequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static llvm::Error RunInTerminal(DAP &dap,
debugger_pid = getpid();
#endif
llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
launch_request, dap.debug_adapter_path, comm_file.m_path, debugger_pid);
launch_request, comm_file.m_path, debugger_pid);
dap.SendReverseRequest<LogFailureResponseHandler>("runInTerminal",
std::move(reverse_request));

Expand Down
3 changes: 2 additions & 1 deletion lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ void SetVariableRequestHandler::operator()(
lldb::SBError error;
bool success = variable.SetValueFromCString(value.data(), error);
if (success) {
VariableDescription desc(variable, dap.enable_auto_variable_summaries);
VariableDescription desc(variable,
dap.configuration.enableAutoVariableSummaries);
EmplaceSafeString(body, "value", desc.display_value);
EmplaceSafeString(body, "type", desc.display_type_name);

Expand Down
2 changes: 1 addition & 1 deletion lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
stack_frames.emplace_back(CreateStackFrame(frame, dap.frame_format));
}

if (dap.display_extended_backtrace && reached_end_of_stack) {
if (dap.configuration.displayExtendedBacktrace && reached_end_of_stack) {
// Check for any extended backtraces.
for (uint32_t bt = 0;
bt < thread.GetProcess().GetNumExtendedBacktraceTypes(); bt++) {
Expand Down
20 changes: 10 additions & 10 deletions lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,10 @@ void VariablesRequestHandler::operator()(
return_var_ref = dap.variables.InsertVariable(stop_return_value,
/*is_permanent=*/false);
}
variables.emplace_back(
CreateVariable(renamed_return_value, return_var_ref, hex,
dap.enable_auto_variable_summaries,
dap.enable_synthetic_child_debugging, false));
variables.emplace_back(CreateVariable(
renamed_return_value, return_var_ref, hex,
dap.configuration.enableAutoVariableSummaries,
dap.configuration.enableSyntheticChildDebugging, false));
}
}

Expand All @@ -197,8 +197,8 @@ void VariablesRequestHandler::operator()(
int64_t var_ref =
dap.variables.InsertVariable(variable, /*is_permanent=*/false);
variables.emplace_back(CreateVariable(
variable, var_ref, hex, dap.enable_auto_variable_summaries,
dap.enable_synthetic_child_debugging,
variable, var_ref, hex, dap.configuration.enableAutoVariableSummaries,
dap.configuration.enableSyntheticChildDebugging,
variable_name_counts[GetNonNullVariableName(variable)] > 1));
}
} else {
Expand All @@ -214,8 +214,8 @@ void VariablesRequestHandler::operator()(
dap.variables.IsPermanentVariableReference(variablesReference);
int64_t var_ref = dap.variables.InsertVariable(child, is_permanent);
variables.emplace_back(CreateVariable(
child, var_ref, hex, dap.enable_auto_variable_summaries,
dap.enable_synthetic_child_debugging,
child, var_ref, hex, dap.configuration.enableAutoVariableSummaries,
dap.configuration.enableSyntheticChildDebugging,
/*is_name_duplicated=*/false, custom_name));
};
const int64_t num_children = variable.GetNumChildren();
Expand All @@ -228,8 +228,8 @@ void VariablesRequestHandler::operator()(
// "[raw]" child that can be used to inspect the raw version of a
// synthetic member. That eliminates the need for the user to go to the
// debug console and type `frame var <variable> to get these values.
if (dap.enable_synthetic_child_debugging && variable.IsSynthetic() &&
i == num_children)
if (dap.configuration.enableSyntheticChildDebugging &&
variable.IsSynthetic() && i == num_children)
addChild(variable.GetNonSyntheticValue(), "[raw]");
}
}
Expand Down
3 changes: 1 addition & 2 deletions lldb/tools/lldb-dap/JSONUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,6 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit &unit) {
/// https://microsoft.github.io/debug-adapter-protocol/specification#Reverse_Requests_RunInTerminal
llvm::json::Object
CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
llvm::StringRef debug_adapter_path,
llvm::StringRef comm_file,
lldb::pid_t debugger_pid) {
llvm::json::Object run_in_terminal_args;
Expand All @@ -1410,7 +1409,7 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,

const auto *launch_request_arguments = launch_request.getObject("arguments");
// The program path must be the first entry in the "args" field
std::vector<std::string> args = {debug_adapter_path.str(), "--comm-file",
std::vector<std::string> args = {DAP::debug_adapter_path.str(), "--comm-file",
comm_file.str()};
if (debugger_pid != LLDB_INVALID_PROCESS_ID) {
args.push_back("--debugger-pid");
Expand Down
5 changes: 0 additions & 5 deletions lldb/tools/lldb-dap/JSONUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,10 +565,6 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit &unit);
/// The original launch_request object whose fields are used to construct
/// the reverse request object.
///
/// \param[in] debug_adapter_path
/// Path to the current debug adapter. It will be used to delegate the
/// launch of the target.
///
/// \param[in] comm_file
/// The fifo file used to communicate the with the target launcher.
///
Expand All @@ -582,7 +578,6 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit &unit);
/// Microsoft.
llvm::json::Object
CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
llvm::StringRef debug_adapter_path,
llvm::StringRef comm_file,
lldb::pid_t debugger_pid);

Expand Down
Loading