aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectThread.cpp
diff options
context:
space:
mode:
authorWalter Erquinigo <wallace@fb.com>2020-10-14 10:26:10 -0700
committerWalter Erquinigo <a20012251@gmail.com>2020-11-05 18:38:03 -0800
commitcfd96f057ba4256fef49518cad43d0a7f591da12 (patch)
treeb42ddff84e7d7250217b020716dbd82331781af0 /lldb/source/Commands/CommandObjectThread.cpp
parentb8745751f167f16717d36867ca46328afa4b7919 (diff)
downloadllvm-cfd96f057ba4256fef49518cad43d0a7f591da12.zip
llvm-cfd96f057ba4256fef49518cad43d0a7f591da12.tar.gz
llvm-cfd96f057ba4256fef49518cad43d0a7f591da12.tar.bz2
[trace][intel-pt] Implement the basic decoding functionality
Depends on D89408. This diff finally implements trace decoding! The current interface is $ trace load /path/to/trace/session/file.json $ thread trace dump instructions thread #1: tid = 3842849, total instructions = 22 [ 0] 0x40052d [ 1] 0x40052d ... [19] 0x400521 $ # simply enter, which is a repeat command [20] 0x40052d [21] 0x400529 ... This doesn't do any disassembly, which will be done in the next diff. Changes: - Added an IntelPTDecoder class, that is a wrapper for libipt, which is the actual library that performs the decoding. - Added TraceThreadDecoder class that decodes traces and memoizes the result to avoid repeating the decoding step. - Added a DecodedThread class, which represents the output from decoding and that for the time being only stores the list of reconstructed instructions. Later it'll contain the function call hierarchy, which will enable reconstructing backtraces. - Added basic APIs for accessing the trace in Trace.h: - GetInstructionCount, which counts the number of instructions traced for a given thread - IsTraceFailed, which returns an Error if decoding a thread failed - ForEachInstruction, which iterates on the instructions traced for a given thread, concealing the internal storage of threads, as plug-ins can decide to generate the instructions on the fly or to store them all in a vector, like I do. - DumpTraceInstructions was updated to print the instructions or show an error message if decoding was impossible. - Tests included Differential Revision: https://reviews.llvm.org/D89283
Diffstat (limited to 'lldb/source/Commands/CommandObjectThread.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp52
1 files changed, 29 insertions, 23 deletions
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 6fbcf7c..5aa77de 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -2200,15 +2200,19 @@ public:
m_count = count;
break;
}
- case 's': {
- int32_t start_position;
- if (option_arg.empty() || option_arg.getAsInteger(0, start_position) ||
- start_position < 0)
+ case 'p': {
+ int32_t position;
+ if (option_arg.empty() || option_arg.getAsInteger(0, position) ||
+ position < 0)
error.SetErrorStringWithFormat(
"invalid integer value for option '%s'",
option_arg.str().c_str());
else
- m_start_position = start_position;
+ m_position = position;
+ break;
+ }
+ case 'r': {
+ m_raw = true;
break;
}
default:
@@ -2219,19 +2223,20 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_count = kDefaultCount;
- m_start_position = kDefaultStartPosition;
+ m_position = llvm::None;
+ m_raw = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
return llvm::makeArrayRef(g_thread_trace_dump_instructions_options);
}
- static const uint32_t kDefaultCount = 20;
- static const uint32_t kDefaultStartPosition = 0;
+ static const size_t kDefaultCount = 20;
// Instance variables to hold the values for command options.
- uint32_t m_count;
- uint32_t m_start_position;
+ size_t m_count;
+ llvm::Optional<ssize_t> m_position;
+ bool m_raw;
};
CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
@@ -2253,30 +2258,24 @@ 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++;
bool status = CommandObjectIterateOverThreads::DoExecute(args, result);
- PrepareRepeatArguments();
- return status;
- }
- void PrepareRepeatArguments() {
- m_repeat_start_position = m_options.m_count + GetStartPosition();
m_create_repeat_command_just_invoked = false;
+ return status;
}
bool IsRepeatCommand() {
return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked;
}
- uint32_t GetStartPosition() {
- return IsRepeatCommand() ? m_repeat_start_position
- : m_options.m_start_position;
- }
-
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
if (!trace_sp) {
@@ -2287,8 +2286,15 @@ protected:
ThreadSP thread_sp =
m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
- trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(),
- m_options.m_count, GetStartPosition());
+ size_t count = m_options.m_count;
+ ssize_t position = m_options.m_position.getValueOr(
+ trace_sp->GetCursorPosition(*thread_sp)) -
+ m_consecutive_repetitions * count;
+ if (position < 0)
+ result.SetError("error: no more data");
+ else
+ trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(),
+ count, position, m_options.m_raw);
return true;
}
@@ -2297,7 +2303,7 @@ protected:
// Repeat command helpers
std::string m_repeat_command;
bool m_create_repeat_command_just_invoked;
- uint32_t m_repeat_start_position;
+ size_t m_consecutive_repetitions = 0;
};
// CommandObjectMultiwordTraceDump