aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Commands/CommandObjectThread.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp70
1 files changed, 45 insertions, 25 deletions
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 292f9c6..e4cf8a4 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -8,6 +8,7 @@
#include "CommandObjectThread.h"
+#include <memory>
#include <sstream>
#include "CommandObjectThreadUtil.h"
@@ -32,6 +33,7 @@
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
#include "lldb/Target/Trace.h"
+#include "lldb/Target/TraceInstructionDumper.h"
#include "lldb/Utility/State.h"
using namespace lldb;
@@ -2004,21 +2006,24 @@ public:
m_count = count;
break;
}
- case 'p': {
- int32_t position;
- if (option_arg.empty() || option_arg.getAsInteger(0, position) ||
- position < 0)
+ case 's': {
+ int32_t skip;
+ if (option_arg.empty() || option_arg.getAsInteger(0, skip) || skip < 0)
error.SetErrorStringWithFormat(
"invalid integer value for option '%s'",
option_arg.str().c_str());
else
- m_position = position;
+ m_skip = skip;
break;
}
case 'r': {
m_raw = true;
break;
}
+ case 'f': {
+ m_forwards = true;
+ break;
+ }
default:
llvm_unreachable("Unimplemented option");
}
@@ -2027,8 +2032,9 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_count = kDefaultCount;
- m_position = llvm::None;
+ m_skip = 0;
m_raw = false;
+ m_forwards = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -2039,14 +2045,15 @@ public:
// Instance variables to hold the values for command options.
size_t m_count;
- llvm::Optional<ssize_t> m_position;
+ size_t m_skip;
bool m_raw;
+ bool m_forwards;
};
CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
: CommandObjectIterateOverThreads(
interpreter, "thread trace dump instructions",
- "Dump the traced instructions for one or more threads. If no "
+ "Dump the traced instructions for one or more threads. If no "
"threads are specified, show the current thread. Use the "
"thread-index \"all\" to see all threads.",
nullptr,
@@ -2063,14 +2070,14 @@ public:
uint32_t index) override {
current_command_args.GetCommandString(m_repeat_command);
m_create_repeat_command_just_invoked = true;
- m_consecutive_repetitions = 0;
return m_repeat_command.c_str();
}
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
- if (IsRepeatCommand())
- m_consecutive_repetitions++;
+ if (!IsRepeatCommand())
+ m_dumpers.clear();
+
bool status = CommandObjectIterateOverThreads::DoExecute(args, result);
m_create_repeat_command_just_invoked = false;
@@ -2082,24 +2089,37 @@ protected:
}
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ Stream &s = result.GetOutputStream();
+
const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
ThreadSP thread_sp =
m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
- if (llvm::Optional<size_t> insn_count =
- trace_sp->GetInstructionCount(*thread_sp)) {
- size_t count = m_options.m_count;
- ssize_t position =
- m_options.m_position.getValueOr((ssize_t)*insn_count - 1) -
- m_consecutive_repetitions * count;
- if (position < 0)
- result.AppendError("error: no more data");
- else
- trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(),
- count, position, m_options.m_raw);
- } else {
- result.AppendError("error: not traced");
+ if (!m_dumpers.count(thread_sp->GetID())) {
+ lldb::TraceCursorUP cursor_up = trace_sp->GetCursor(*thread_sp);
+ // Set up the cursor and return the presentation index of the first
+ // instruction to dump after skipping instructions.
+ auto setUpCursor = [&]() {
+ cursor_up->SetForwards(m_options.m_forwards);
+ if (m_options.m_forwards)
+ return cursor_up->Seek(m_options.m_skip, TraceCursor::SeekType::Set);
+ return -cursor_up->Seek(-m_options.m_skip, TraceCursor::SeekType::End);
+ };
+
+ int initial_index = setUpCursor();
+
+ auto dumper = std::make_unique<TraceInstructionDumper>(
+ std::move(cursor_up), initial_index, m_options.m_raw);
+
+ // This happens when the seek value was more than the number of available
+ // instructions.
+ if (std::abs(initial_index) < (int)m_options.m_skip)
+ dumper->SetNoMoreData();
+
+ m_dumpers[thread_sp->GetID()] = std::move(dumper);
}
+
+ m_dumpers[thread_sp->GetID()]->DumpInstructions(s, m_options.m_count);
return true;
}
@@ -2108,7 +2128,7 @@ protected:
// Repeat command helpers
std::string m_repeat_command;
bool m_create_repeat_command_just_invoked;
- size_t m_consecutive_repetitions = 0;
+ std::map<lldb::tid_t, std::unique_ptr<TraceInstructionDumper>> m_dumpers;
};
// CommandObjectMultiwordTraceDump