[Lldb-commits] [lldb] fb01f19 - [lldb][lldb-dap] fix repeating commands in repl mode (#135008)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 24 18:32:55 PDT 2025
Author: Ebuka Ezike
Date: 2025-04-25T02:32:52+01:00
New Revision: fb01f19f3cf6b3317983b06a7dbf5ed143072990
URL: https://github.com/llvm/llvm-project/commit/fb01f19f3cf6b3317983b06a7dbf5ed143072990
DIFF: https://github.com/llvm/llvm-project/commit/fb01f19f3cf6b3317983b06a7dbf5ed143072990.diff
LOG: [lldb][lldb-dap] fix repeating commands in repl mode (#135008)
Fixes #131589
Add a new parameter to the RunCommands functions to control the echoing of
commands
---------
Signed-off-by: Ebuka Ezike <yerimyah1 at gmail.com>
Co-authored-by: Walter Erquinigo <a20012251 at gmail.com>
Added:
Modified:
lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
lldb/tools/lldb-dap/DAP.cpp
lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
lldb/tools/lldb-dap/LLDBUtils.cpp
lldb/tools/lldb-dap/LLDBUtils.h
Removed:
################################################################################
diff --git a/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py b/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
index 251d77d79d080..e2f843bd337a6 100644
--- a/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
+++ b/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
@@ -101,7 +101,7 @@ def run_test_evaluate_expressions(
if context == "repl":
# In the repl context expressions may be interpreted as lldb
# commands since no variables have the same name as the command.
- self.assertEvaluate("list", r"\(lldb\) list\n.*")
+ self.assertEvaluate("list", r".*")
else:
self.assertEvaluateFailure("list") # local variable of a_function
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index 1599ee5de7075..4303f2d3a5193 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -523,11 +523,9 @@ def test_version(self):
)
version_eval_output = version_eval_response["body"]["result"]
- # The first line is the prompt line like "(lldb) version", so we skip it.
- version_eval_output_without_prompt_line = version_eval_output.splitlines()[1:]
version_string = self.dap_server.get_initialize_value("$__lldb_version")
self.assertEqual(
- version_eval_output_without_prompt_line,
+ version_eval_output.splitlines(),
version_string.splitlines(),
"version string does not match",
)
diff --git a/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py b/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
index 7c77fc8541b93..c6f59949d668e 100644
--- a/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
+++ b/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
@@ -28,15 +28,12 @@ def test_completions(self):
self.set_source_breakpoints(source, [breakpoint1_line, breakpoint2_line])
- self.assertEvaluate(
- "`command regex user_command s/^$/platform/", r"\(lldb\) command regex"
- )
- self.assertEvaluate(
- "`command alias alias_command platform", r"\(lldb\) command alias"
- )
+ # The result of the commands should return the empty string.
+ self.assertEvaluate("`command regex user_command s/^$/platform/", r"^$")
+ self.assertEvaluate("`command alias alias_command platform", r"^$")
self.assertEvaluate(
"`command alias alias_command_with_arg platform select --sysroot %1 remote-linux",
- r"\(lldb\) command alias",
+ r"^$",
)
self.continue_to_next_stop()
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 134762711b89d..20ef27f6054ec 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -594,8 +594,9 @@ ReplMode DAP::DetectReplMode(lldb::SBFrame frame, std::string &expression,
bool DAP::RunLLDBCommands(llvm::StringRef prefix,
llvm::ArrayRef<std::string> commands) {
bool required_command_failed = false;
- std::string output =
- ::RunLLDBCommands(debugger, prefix, commands, required_command_failed);
+ std::string output = ::RunLLDBCommands(
+ debugger, prefix, commands, required_command_failed,
+ /*parse_command_directives*/ true, /*echo_commands*/ true);
SendOutput(OutputType::Console, output);
return !required_command_failed;
}
diff --git a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
index 8ed09fa2a931a..5ce133c33b7e1 100644
--- a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
@@ -163,8 +163,12 @@ void EvaluateRequestHandler::operator()(
if (frame.IsValid()) {
dap.focus_tid = frame.GetThread().GetThreadID();
}
- auto result = RunLLDBCommandsVerbatim(dap.debugger, llvm::StringRef(),
- {std::string(expression)});
+
+ bool required_command_failed = false;
+ std::string result = RunLLDBCommands(
+ dap.debugger, llvm::StringRef(), {expression}, required_command_failed,
+ /*parse_command_directives=*/false, /*echo_commands=*/false);
+
EmplaceSafeString(body, "result", result);
body.try_emplace("variablesReference", (int64_t)0);
} else {
diff --git a/lldb/tools/lldb-dap/LLDBUtils.cpp b/lldb/tools/lldb-dap/LLDBUtils.cpp
index a27beff0b030d..f096477cc7b49 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.cpp
+++ b/lldb/tools/lldb-dap/LLDBUtils.cpp
@@ -17,12 +17,29 @@ namespace lldb_dap {
bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
const llvm::ArrayRef<std::string> &commands,
- llvm::raw_ostream &strm, bool parse_command_directives) {
+ llvm::raw_ostream &strm, bool parse_command_directives,
+ bool echo_commands) {
if (commands.empty())
return true;
bool did_print_prefix = false;
+ // We only need the prompt when echoing commands.
+ std::string prompt_string;
+ if (echo_commands) {
+ prompt_string = "(lldb) ";
+
+ // Get the current prompt from settings.
+ if (const lldb::SBStructuredData prompt = debugger.GetSetting("prompt")) {
+ const size_t prompt_length = prompt.GetStringValue(nullptr, 0);
+
+ if (prompt_length != 0) {
+ prompt_string.resize(prompt_length + 1);
+ prompt.GetStringValue(prompt_string.data(), prompt_string.length());
+ }
+ }
+ }
+
lldb::SBCommandInterpreter interp = debugger.GetCommandInterpreter();
for (llvm::StringRef command : commands) {
lldb::SBCommandReturnObject result;
@@ -60,7 +77,10 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
strm << prefix << "\n";
did_print_prefix = true;
}
- strm << "(lldb) " << command << "\n";
+
+ if (echo_commands)
+ strm << prompt_string.c_str() << command << '\n';
+
auto output_len = result.GetOutputSize();
if (output_len) {
const char *output = result.GetOutput();
@@ -81,23 +101,16 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
std::string RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
const llvm::ArrayRef<std::string> &commands,
bool &required_command_failed,
- bool parse_command_directives) {
+ bool parse_command_directives, bool echo_commands) {
required_command_failed = false;
std::string s;
llvm::raw_string_ostream strm(s);
- required_command_failed = !RunLLDBCommands(debugger, prefix, commands, strm,
- parse_command_directives);
+ required_command_failed =
+ !RunLLDBCommands(debugger, prefix, commands, strm,
+ parse_command_directives, echo_commands);
return s;
}
-std::string
-RunLLDBCommandsVerbatim(lldb::SBDebugger &debugger, llvm::StringRef prefix,
- const llvm::ArrayRef<std::string> &commands) {
- bool required_command_failed = false;
- return RunLLDBCommands(debugger, prefix, commands, required_command_failed,
- /*parse_command_directives=*/false);
-}
-
bool ThreadHasStopReason(lldb::SBThread &thread) {
switch (thread.GetStopReason()) {
case lldb::eStopReasonTrace:
diff --git a/lldb/tools/lldb-dap/LLDBUtils.h b/lldb/tools/lldb-dap/LLDBUtils.h
index 2c57847303cb3..e4d2818a31605 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.h
+++ b/lldb/tools/lldb-dap/LLDBUtils.h
@@ -51,12 +51,16 @@ namespace lldb_dap {
/// If \b false, then command prefixes like \b ! or \b ? are not parsed and
/// each command is executed verbatim.
///
+/// \param[in] echo_commands
+/// If \b true, the command are echoed to the stream.
+///
/// \return
/// \b true, unless a command prefixed with \b ! fails and parsing of
/// command directives is enabled.
bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
const llvm::ArrayRef<std::string> &commands,
- llvm::raw_ostream &strm, bool parse_command_directives);
+ llvm::raw_ostream &strm, bool parse_command_directives,
+ bool echo_commands);
/// Run a list of LLDB commands in the LLDB command interpreter.
///
@@ -81,18 +85,17 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
/// If \b false, then command prefixes like \b ! or \b ? are not parsed and
/// each command is executed verbatim.
///
+/// \param[in] echo_commands
+/// If \b true, the command are echoed to the stream.
+///
/// \return
/// A std::string that contains the prefix and all commands and
/// command output.
std::string RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
const llvm::ArrayRef<std::string> &commands,
bool &required_command_failed,
- bool parse_command_directives = true);
-
-/// Similar to the method above, but without parsing command directives.
-std::string
-RunLLDBCommandsVerbatim(lldb::SBDebugger &debugger, llvm::StringRef prefix,
- const llvm::ArrayRef<std::string> &commands);
+ bool parse_command_directives = true,
+ bool echo_commands = false);
/// Check if a thread has a stop reason.
///
More information about the lldb-commits
mailing list