Skip to content

Commit fb01f19

Browse files
[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 <[email protected]> Co-authored-by: Walter Erquinigo <[email protected]>
1 parent f0c61d2 commit fb01f19

File tree

7 files changed

+51
-35
lines changed

7 files changed

+51
-35
lines changed

lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def run_test_evaluate_expressions(
101101
if context == "repl":
102102
# In the repl context expressions may be interpreted as lldb
103103
# commands since no variables have the same name as the command.
104-
self.assertEvaluate("list", r"\(lldb\) list\n.*")
104+
self.assertEvaluate("list", r".*")
105105
else:
106106
self.assertEvaluateFailure("list") # local variable of a_function
107107

lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,11 +523,9 @@ def test_version(self):
523523
)
524524
version_eval_output = version_eval_response["body"]["result"]
525525

526-
# The first line is the prompt line like "(lldb) version", so we skip it.
527-
version_eval_output_without_prompt_line = version_eval_output.splitlines()[1:]
528526
version_string = self.dap_server.get_initialize_value("$__lldb_version")
529527
self.assertEqual(
530-
version_eval_output_without_prompt_line,
528+
version_eval_output.splitlines(),
531529
version_string.splitlines(),
532530
"version string does not match",
533531
)

lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,12 @@ def test_completions(self):
2828

2929
self.set_source_breakpoints(source, [breakpoint1_line, breakpoint2_line])
3030

31-
self.assertEvaluate(
32-
"`command regex user_command s/^$/platform/", r"\(lldb\) command regex"
33-
)
34-
self.assertEvaluate(
35-
"`command alias alias_command platform", r"\(lldb\) command alias"
36-
)
31+
# The result of the commands should return the empty string.
32+
self.assertEvaluate("`command regex user_command s/^$/platform/", r"^$")
33+
self.assertEvaluate("`command alias alias_command platform", r"^$")
3734
self.assertEvaluate(
3835
"`command alias alias_command_with_arg platform select --sysroot %1 remote-linux",
39-
r"\(lldb\) command alias",
36+
r"^$",
4037
)
4138

4239
self.continue_to_next_stop()

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,9 @@ ReplMode DAP::DetectReplMode(lldb::SBFrame frame, std::string &expression,
594594
bool DAP::RunLLDBCommands(llvm::StringRef prefix,
595595
llvm::ArrayRef<std::string> commands) {
596596
bool required_command_failed = false;
597-
std::string output =
598-
::RunLLDBCommands(debugger, prefix, commands, required_command_failed);
597+
std::string output = ::RunLLDBCommands(
598+
debugger, prefix, commands, required_command_failed,
599+
/*parse_command_directives*/ true, /*echo_commands*/ true);
599600
SendOutput(OutputType::Console, output);
600601
return !required_command_failed;
601602
}

lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,12 @@ void EvaluateRequestHandler::operator()(
163163
if (frame.IsValid()) {
164164
dap.focus_tid = frame.GetThread().GetThreadID();
165165
}
166-
auto result = RunLLDBCommandsVerbatim(dap.debugger, llvm::StringRef(),
167-
{std::string(expression)});
166+
167+
bool required_command_failed = false;
168+
std::string result = RunLLDBCommands(
169+
dap.debugger, llvm::StringRef(), {expression}, required_command_failed,
170+
/*parse_command_directives=*/false, /*echo_commands=*/false);
171+
168172
EmplaceSafeString(body, "result", result);
169173
body.try_emplace("variablesReference", (int64_t)0);
170174
} else {

lldb/tools/lldb-dap/LLDBUtils.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,29 @@ namespace lldb_dap {
1717

1818
bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
1919
const llvm::ArrayRef<std::string> &commands,
20-
llvm::raw_ostream &strm, bool parse_command_directives) {
20+
llvm::raw_ostream &strm, bool parse_command_directives,
21+
bool echo_commands) {
2122
if (commands.empty())
2223
return true;
2324

2425
bool did_print_prefix = false;
2526

27+
// We only need the prompt when echoing commands.
28+
std::string prompt_string;
29+
if (echo_commands) {
30+
prompt_string = "(lldb) ";
31+
32+
// Get the current prompt from settings.
33+
if (const lldb::SBStructuredData prompt = debugger.GetSetting("prompt")) {
34+
const size_t prompt_length = prompt.GetStringValue(nullptr, 0);
35+
36+
if (prompt_length != 0) {
37+
prompt_string.resize(prompt_length + 1);
38+
prompt.GetStringValue(prompt_string.data(), prompt_string.length());
39+
}
40+
}
41+
}
42+
2643
lldb::SBCommandInterpreter interp = debugger.GetCommandInterpreter();
2744
for (llvm::StringRef command : commands) {
2845
lldb::SBCommandReturnObject result;
@@ -60,7 +77,10 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
6077
strm << prefix << "\n";
6178
did_print_prefix = true;
6279
}
63-
strm << "(lldb) " << command << "\n";
80+
81+
if (echo_commands)
82+
strm << prompt_string.c_str() << command << '\n';
83+
6484
auto output_len = result.GetOutputSize();
6585
if (output_len) {
6686
const char *output = result.GetOutput();
@@ -81,23 +101,16 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
81101
std::string RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
82102
const llvm::ArrayRef<std::string> &commands,
83103
bool &required_command_failed,
84-
bool parse_command_directives) {
104+
bool parse_command_directives, bool echo_commands) {
85105
required_command_failed = false;
86106
std::string s;
87107
llvm::raw_string_ostream strm(s);
88-
required_command_failed = !RunLLDBCommands(debugger, prefix, commands, strm,
89-
parse_command_directives);
108+
required_command_failed =
109+
!RunLLDBCommands(debugger, prefix, commands, strm,
110+
parse_command_directives, echo_commands);
90111
return s;
91112
}
92113

93-
std::string
94-
RunLLDBCommandsVerbatim(lldb::SBDebugger &debugger, llvm::StringRef prefix,
95-
const llvm::ArrayRef<std::string> &commands) {
96-
bool required_command_failed = false;
97-
return RunLLDBCommands(debugger, prefix, commands, required_command_failed,
98-
/*parse_command_directives=*/false);
99-
}
100-
101114
bool ThreadHasStopReason(lldb::SBThread &thread) {
102115
switch (thread.GetStopReason()) {
103116
case lldb::eStopReasonTrace:

lldb/tools/lldb-dap/LLDBUtils.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,16 @@ namespace lldb_dap {
5151
/// If \b false, then command prefixes like \b ! or \b ? are not parsed and
5252
/// each command is executed verbatim.
5353
///
54+
/// \param[in] echo_commands
55+
/// If \b true, the command are echoed to the stream.
56+
///
5457
/// \return
5558
/// \b true, unless a command prefixed with \b ! fails and parsing of
5659
/// command directives is enabled.
5760
bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
5861
const llvm::ArrayRef<std::string> &commands,
59-
llvm::raw_ostream &strm, bool parse_command_directives);
62+
llvm::raw_ostream &strm, bool parse_command_directives,
63+
bool echo_commands);
6064

6165
/// Run a list of LLDB commands in the LLDB command interpreter.
6266
///
@@ -81,18 +85,17 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
8185
/// If \b false, then command prefixes like \b ! or \b ? are not parsed and
8286
/// each command is executed verbatim.
8387
///
88+
/// \param[in] echo_commands
89+
/// If \b true, the command are echoed to the stream.
90+
///
8491
/// \return
8592
/// A std::string that contains the prefix and all commands and
8693
/// command output.
8794
std::string RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
8895
const llvm::ArrayRef<std::string> &commands,
8996
bool &required_command_failed,
90-
bool parse_command_directives = true);
91-
92-
/// Similar to the method above, but without parsing command directives.
93-
std::string
94-
RunLLDBCommandsVerbatim(lldb::SBDebugger &debugger, llvm::StringRef prefix,
95-
const llvm::ArrayRef<std::string> &commands);
97+
bool parse_command_directives = true,
98+
bool echo_commands = false);
9699

97100
/// Check if a thread has a stop reason.
98101
///

0 commit comments

Comments
 (0)