https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/133960
>From 11ff51134e0632d800806e2319ce14bbb914ec2f Mon Sep 17 00:00:00 2001 From: John Harrison <harj...@google.com> Date: Tue, 1 Apr 2025 11:27:31 -0700 Subject: [PATCH 1/2] [lldb-dap] Creating a common configuration structure for launch and attach requests. This moves all the common settings of the launch and attach operations into the `lldb_dap::protocol::DAPConfiguration`. These common settings can be in both `launch` and `attach` requests and allows us to isolate the DAP configuration operations into a single common location. This is split out from #133624. --- lldb/tools/lldb-dap/DAP.cpp | 41 +++++----- lldb/tools/lldb-dap/DAP.h | 23 ++---- .../lldb-dap/Handler/AttachRequestHandler.cpp | 21 +++--- .../lldb-dap/Handler/CompletionsHandler.cpp | 7 +- .../Handler/EvaluateRequestHandler.cpp | 3 +- .../lldb-dap/Handler/LaunchRequestHandler.cpp | 21 +++--- .../tools/lldb-dap/Handler/RequestHandler.cpp | 2 +- .../Handler/SetVariableRequestHandler.cpp | 3 +- .../Handler/StackTraceRequestHandler.cpp | 2 +- .../Handler/VariablesRequestHandler.cpp | 20 ++--- lldb/tools/lldb-dap/JSONUtils.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.h | 5 -- .../lldb-dap/Protocol/ProtocolRequests.h | 75 +++++++++++++++++++ lldb/tools/lldb-dap/SourceBreakpoint.cpp | 6 +- lldb/tools/lldb-dap/lldb-dap.cpp | 15 ++-- 15 files changed, 156 insertions(+), 91 deletions(-) diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 8951384212f11..9361ba968e9c2 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -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; @@ -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; } @@ -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 @@ -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 diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 4357bdd5cc80f..165e660b8489d 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -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" @@ -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::DAPConfiguration configuration; lldb::SBDebugger debugger; lldb::SBTarget target; Variables variables; @@ -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 @@ -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. @@ -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 @@ -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 @@ -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(); diff --git a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp index 20f7c80a1ed90..5e622f3d3dcd4 100644 --- a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp @@ -63,11 +63,12 @@ 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 = @@ -75,16 +76,16 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const { 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("")); diff --git a/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp b/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp index 5414aaeb2c317..c72fc5686cd5b 100644 --- a/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp @@ -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 diff --git a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp index e9f08a1017abc..8ed09fa2a931a 100644 --- a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp @@ -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; diff --git a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp index f64c186376a36..5f14cb074e37e 100644 --- a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp @@ -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("")); diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp index f067dfc5544fe..576f0dda64cf4 100644 --- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp @@ -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)); diff --git a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp index a7896b7fefa29..c48bcd84c9ddc 100644 --- a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp @@ -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); diff --git a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp index 220be0f99be6b..a58e3325af100 100644 --- a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp @@ -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++) { diff --git a/lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp index 6bb0a0f160499..19bcca2b22b9b 100644 --- a/lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp @@ -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)); } } @@ -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 { @@ -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(); @@ -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]"); } } diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 590137e48199d..7660403666150 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -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; @@ -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"); diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h index 5d403d39a76d4..da91797290ff0 100644 --- a/lldb/tools/lldb-dap/JSONUtils.h +++ b/lldb/tools/lldb-dap/JSONUtils.h @@ -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. /// @@ -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); diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h index 927106997953a..71ab9c0e3448b 100644 --- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h +++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h @@ -118,6 +118,81 @@ bool fromJSON(const llvm::json::Value &, InitializeRequestArguments &, /// Response to `initialize` request. The capabilities of this debug adapter. using InitializeResponseBody = std::optional<Capabilities>; +/// DAP Launch and Attach common configurations. +struct DAPConfiguration { + /// Specify a working directory to use when launching `lldb-dap`. If the debug + /// information in your executable contains relative paths, this option can be + /// used so that `lldb-dap` can find source files and object files that have + /// relative paths. + std::optional<std::string> debuggerRoot; + + /// Enable auto generated summaries for variables when no summaries exist for + /// a given type. This feature can cause performance delays in large projects + /// when viewing variables. + bool enableAutoVariableSummaries = false; + + /// If a variable is displayed using a synthetic children, also display the + /// actual contents of the variable at the end under a [raw] entry. This is + /// useful when creating sythetic child plug-ins as it lets you see the actual + /// contents of the variable. + bool enableSyntheticChildDebugging = false; + + /// Enable language specific extended backtraces. + bool displayExtendedBacktrace = false; + + /// The escape prefix to use for executing regular LLDB commands in the Debug + /// Console, instead of printing variables. Defaults to a backtick. If it's an + /// empty string, then all expression in the Debug Console are treated as + /// regular LLDB commands. + std::string commandEscapePrefix = "`"; + + /// If non-empty, stack frames will have descriptions generated based on the + /// provided format. See https://lldb.llvm.org/use/formatting.html for an + /// explanation on format strings for frames. If the format string contains + /// errors, an error message will be displayed on the Debug Console and the + /// default frame names will be used. This might come with a performance cost + /// because debug information might need to be processed to generate the + /// description. + std::optional<std::string> customFrameFormat; + + /// Same as `customFrameFormat`, but for threads instead of stack frames. + std::optional<std::string> customThreadFormat; + + /// Specify a source path to remap "./" to allow full paths to be used when + /// setting breakpoints in binaries that have relative source paths. + std::optional<std::string> sourcePath; + + /// Specify an array of path re-mappings. Each element in the array must be a + /// two element array containing a source and destination pathname. Overrides + /// sourcePath. + std::vector<std::pair<std::string, std::string>> sourceMap; + + /// LLDB commands executed upon debugger startup prior to creating the LLDB + /// target. + std::vector<std::string> preInitCommands; + + /// LLDB commands executed upon debugger startup prior to creating the LLDB + /// target. + std::vector<std::string> initCommands; + + /// LLDB commands executed just before launching/attaching, after the LLDB + /// target has been created. + std::vector<std::string> preRunCommands; + + /// LLDB commands executed just after launching/attaching, after the LLDB + /// target has been created. + std::vector<std::string> postRunCommands; + + /// LLDB commands executed just after each stop. + std::vector<std::string> stopCommands; + + /// LLDB commands executed when the program exits. + std::vector<std::string> exitCommands; + + /// LLDB commands executed when the debugging session ends. + std::vector<std::string> terminateCommands; +}; + /// Arguments for `source` request. struct SourceArguments { /// Specifies the source content to load. Either `source.path` or diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp b/lldb/tools/lldb-dap/SourceBreakpoint.cpp index 150fa6af44d3a..ffc3b22d86243 100644 --- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp +++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp @@ -319,9 +319,9 @@ bool SourceBreakpoint::BreakpointHitCallback( frame.GetValueForVariablePath(expr, lldb::eDynamicDontRunTarget); if (value.GetError().Fail()) value = frame.EvaluateExpression(expr); - output += - VariableDescription(value, bp->m_dap.enable_auto_variable_summaries) - .display_value; + output += VariableDescription( + value, bp->m_dap.configuration.enableAutoVariableSummaries) + .display_value; } else { output += messagePart.text; } diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index b91c62e921428..16565522078f0 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -43,7 +43,6 @@ #include <cstdio> #include <cstdlib> #include <fcntl.h> -#include <fstream> #include <map> #include <memory> #include <mutex> @@ -282,8 +281,7 @@ validateConnection(llvm::StringRef conn) { static llvm::Error serveConnection(const Socket::SocketProtocol &protocol, const std::string &name, - Log *log, llvm::StringRef program_path, - const ReplMode default_repl_mode, + Log *log, const ReplMode default_repl_mode, const std::vector<std::string> &pre_init_commands) { Status status; static std::unique_ptr<Socket> listener = Socket::Create(protocol, status); @@ -328,8 +326,7 @@ serveConnection(const Socket::SocketProtocol &protocol, const std::string &name, &dap_sessions]() { llvm::set_thread_name(client_name + ".runloop"); Transport transport(client_name, log, io, io); - DAP dap(program_path, log, default_repl_mode, pre_init_commands, - transport); + DAP dap(log, default_repl_mode, pre_init_commands, transport); if (auto Err = dap.ConfigureIO()) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), @@ -410,6 +407,7 @@ int main(int argc, char *argv[]) { llvm::SmallString<256> program_path(argv[0]); llvm::sys::fs::make_absolute(program_path); + DAP::debug_adapter_path = program_path; LLDBDAPOptTable T; unsigned MAI, MAC; @@ -541,8 +539,8 @@ int main(int argc, char *argv[]) { Socket::SocketProtocol protocol; std::string name; std::tie(protocol, name) = *maybeProtoclAndName; - if (auto Err = serveConnection(protocol, name, log.get(), program_path, - default_repl_mode, pre_init_commands)) { + if (auto Err = serveConnection(protocol, name, log.get(), default_repl_mode, + pre_init_commands)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "Connection failed: "); return EXIT_FAILURE; @@ -577,8 +575,7 @@ int main(int argc, char *argv[]) { constexpr llvm::StringLiteral client_name = "stdin/stdout"; Transport transport(client_name, log.get(), input, output); - DAP dap(program_path, log.get(), default_repl_mode, pre_init_commands, - transport); + DAP dap(log.get(), default_repl_mode, pre_init_commands, transport); // stdout/stderr redirection to the IDE's console if (auto Err = dap.ConfigureIO(stdout, stderr)) { >From b04648328527a194f8d496cb1f1ccb74e322490a Mon Sep 17 00:00:00 2001 From: John Harrison <harj...@google.com> Date: Thu, 3 Apr 2025 08:25:37 -0700 Subject: [PATCH 2/2] Renaming DAPConfiguration > Configuration. --- lldb/tools/lldb-dap/DAP.h | 2 +- lldb/tools/lldb-dap/Protocol/ProtocolRequests.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 165e660b8489d..2790c5fb5cc9a 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -156,7 +156,7 @@ struct DAP { OutputRedirector out; OutputRedirector err; /// Configuration specified by the launch or attach commands. - protocol::DAPConfiguration configuration; + protocol::Configuration configuration; lldb::SBDebugger debugger; lldb::SBTarget target; Variables variables; diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h index 71ab9c0e3448b..64c5116315239 100644 --- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h +++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h @@ -119,7 +119,7 @@ bool fromJSON(const llvm::json::Value &, InitializeRequestArguments &, using InitializeResponseBody = std::optional<Capabilities>; /// DAP Launch and Attach common configurations. -struct DAPConfiguration { +struct Configuration { /// Specify a working directory to use when launching `lldb-dap`. If the debug /// information in your executable contains relative paths, this option can be /// used so that `lldb-dap` can find source files and object files that have _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits