diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -2003,14 +2003,14 @@ // If we got here when empty_command was true, then this command is a // stored "repeat command" which we should give a chance to produce it's // repeat command, even though we don't add repeat commands to the history. - if (add_to_history || empty_command) { - Args command_args(command_string); - std::optional repeat_command = - cmd_obj->GetRepeatCommand(command_args, 0); - if (repeat_command) - m_repeat_command.assign(*repeat_command); - else - m_repeat_command.assign(original_command_string); + Args command_args(command_string); + std::optional repeat_command = + cmd_obj->GetRepeatCommand(command_args, 0); + if (repeat_command) { + LLDB_LOGF(log, "Repeat command: %s", repeat_command->data()); + m_repeat_command.assign(*repeat_command); + } else { + m_repeat_command.assign(original_command_string); } if (add_to_history) diff --git a/lldb/test/API/functionalities/alias/TestBtAliasRepeat.py b/lldb/test/API/functionalities/alias/TestBtAliasRepeat.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/functionalities/alias/TestBtAliasRepeat.py @@ -0,0 +1,19 @@ +import lldb +from lldbsuite.test.lldbtest import TestBase +from lldbsuite.test import lldbutil + + +class TestCase(TestBase): + def test(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "return", lldb.SBFileSpec("main.c")) + + # Expect "frame #0" but not "frame #1". + self.expect("bt 1", inHistory=True, patterns=["frame #0", "^(?!.*frame #1)"]) + + # Run an empty command to run the repeat command for `bt`. + # The repeat command for `bt N` lists the subsequent N frames. + # + # In this case, after printing the frame 0 with `bt 1`, the repeat + # command will print "frame #1" (and won't print "frame #0"). + self.expect("", patterns=["^(?!.*frame #0)", "frame #1"])