diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 0ad3cc090f7d6..f12d90603ec7e 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -2032,7 +2032,7 @@ class CommandObjectTraceExport : public CommandObjectMultiword { unsigned i = 0; for (llvm::StringRef plugin_name = - PluginManager::GetTraceExporterPluginNameAtIndex(i++); + PluginManager::GetTraceExporterPluginNameAtIndex(i); !plugin_name.empty(); plugin_name = PluginManager::GetTraceExporterPluginNameAtIndex(i++)) { if (ThreadTraceExportCommandCreator command_creator = @@ -2147,6 +2147,10 @@ class CommandObjectTraceDumpInstructions m_show_tsc = true; break; } + case 'C': { + m_continue = true; + break; + } default: llvm_unreachable("Unimplemented option"); } @@ -2159,6 +2163,7 @@ class CommandObjectTraceDumpInstructions m_raw = false; m_forwards = false; m_show_tsc = false; + m_continue = false; } llvm::ArrayRef GetDefinitions() override { @@ -2173,6 +2178,7 @@ class CommandObjectTraceDumpInstructions bool m_raw; bool m_forwards; bool m_show_tsc; + bool m_continue; }; CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter) @@ -2192,24 +2198,19 @@ class CommandObjectTraceDumpInstructions llvm::Optional GetRepeatCommand(Args ¤t_command_args, uint32_t index) override { - current_command_args.GetCommandString(m_repeat_command); - m_create_repeat_command_just_invoked = true; - return m_repeat_command; + std::string cmd; + current_command_args.GetCommandString(cmd); + if (cmd.find("--continue") == std::string::npos) + cmd += " --continue"; + return cmd; } protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - if (!IsRepeatCommand()) + if (!m_options.m_continue) m_dumpers.clear(); - bool status = CommandObjectIterateOverThreads::DoExecute(args, result); - - m_create_repeat_command_just_invoked = false; - return status; - } - - bool IsRepeatCommand() { - return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked; + return CommandObjectIterateOverThreads::DoExecute(args, result); } bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { @@ -2249,10 +2250,6 @@ class CommandObjectTraceDumpInstructions } CommandOptions m_options; - - // Repeat command helpers - std::string m_repeat_command; - bool m_create_repeat_command_just_invoked = false; std::map> m_dumpers; }; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 13f9fb70f9da8..2720666cc5f0d 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1116,6 +1116,12 @@ let Command = "thread trace dump instructions" in { def thread_trace_dump_instructions_show_tsc : Option<"tsc", "t">, Group<1>, Desc<"For each instruction, print the corresponding timestamp counter if available.">; + def thread_trace_dump_instructions_continue: Option<"continue", "C">, + Group<1>, + Desc<"Continue dumping instructions right where the previous invocation of this " + "command was left, or from the beginning if this is the first invocation. The --skip " + "argument is discarded and the other arguments are preserved from the previous " + "invocation when possible.">; } let Command = "thread trace dump info" in { diff --git a/lldb/test/API/commands/trace/TestTraceDumpInfo.py b/lldb/test/API/commands/trace/TestTraceDumpInfo.py index b06840865232b..99877aaa27ae5 100644 --- a/lldb/test/API/commands/trace/TestTraceDumpInfo.py +++ b/lldb/test/API/commands/trace/TestTraceDumpInfo.py @@ -18,7 +18,7 @@ def testErrorMessages(self): os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) self.expect("thread trace dump info", - substrs=["error: invalid process"], + substrs=["error: Command requires a current process."], error=True) # Now we check the output when there's a running target without a trace diff --git a/lldb/test/API/commands/trace/TestTraceDumpInstructions.py b/lldb/test/API/commands/trace/TestTraceDumpInstructions.py index 745a4c61a5d56..7b2e629c6e18f 100644 --- a/lldb/test/API/commands/trace/TestTraceDumpInstructions.py +++ b/lldb/test/API/commands/trace/TestTraceDumpInstructions.py @@ -19,7 +19,7 @@ def testErrorMessages(self): os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) self.expect("thread trace dump instructions", - substrs=["error: invalid process"], + substrs=["error: Command requires a current process."], error=True) # Now we check the output when there's a running target without a trace diff --git a/lldb/test/API/commands/trace/TestTraceExport.py b/lldb/test/API/commands/trace/TestTraceExport.py index 6cff0d2621aeb..7126424d5a2d9 100644 --- a/lldb/test/API/commands/trace/TestTraceExport.py +++ b/lldb/test/API/commands/trace/TestTraceExport.py @@ -23,7 +23,7 @@ def testErrorMessages(self): os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) self.expect(f"thread trace export ctf --file {ctf_test_file}", - substrs=["error: invalid process"], + substrs=["error: Command requires a current process."], error=True) # Now we check the output when there's a running target without a trace @@ -172,4 +172,3 @@ def testHtrBasicSuperBlockPassSequenceCheck(self): data_index = index_of_first_layer_1_block for i in range(len(expected_block_names)): self.assertTrue(data[data_index + i]['name'] == expected_block_names[i]) - diff --git a/lldb/test/API/commands/trace/TestTraceSave.py b/lldb/test/API/commands/trace/TestTraceSave.py index 7306a0808e018..4037c729ca924 100644 --- a/lldb/test/API/commands/trace/TestTraceSave.py +++ b/lldb/test/API/commands/trace/TestTraceSave.py @@ -18,7 +18,7 @@ def testErrorMessages(self): os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) self.expect("process trace save", - substrs=["error: invalid process"], + substrs=["error: Command requires a current process."], error=True) # Now we check the output when there's a running target without a trace