
This diff introduces Hierarchical Trace Representation (HTR) and creates the `thread trace export ctf -f <filename> -t <thread_id>` command to export an Intel PT trace's HTR to Chrome Trace Format (CTF) for visualization. See `lldb/docs/htr.rst` for context/documentation on HTR. **Overview of Changes** - Add HTR documentation (see `lldb/docs/htr.rst`) - Add HTR structures (layer, block, block metadata) - Implement "Basic Super Block" HTR pass - Add 'thread trace export ctf' command to export the HTR of an Intel PT trace to Chrome Trace Format (CTF) As this diff is the first iteration of HTR and trace visualization, future diffs will build on this work by generalizing the internal design of HTR and implementing new HTR passes that provide better trace summarization/visualization. See attached video for an example of Intel PT trace visualization: {F17851042} Original Author: jj10306 Submitted by: wallace Reviewed By: wallace, clayborg Differential Revision: https://reviews.llvm.org/D105741
93 lines
3.0 KiB
C++
93 lines
3.0 KiB
C++
//===-- CommandObjectThreadTraceExportCTF.cpp -----------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CommandObjectThreadTraceExportCTF.h"
|
|
|
|
#include "../common/TraceHTR.h"
|
|
#include "lldb/Host/OptionParser.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Trace.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
using namespace lldb_private::ctf;
|
|
using namespace llvm;
|
|
|
|
// CommandObjectThreadTraceExportCTF
|
|
|
|
#define LLDB_OPTIONS_thread_trace_export_ctf
|
|
#include "TraceExporterCTFCommandOptions.inc"
|
|
|
|
Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue(
|
|
uint32_t option_idx, llvm::StringRef option_arg,
|
|
ExecutionContext *execution_context) {
|
|
Status error;
|
|
const int short_option = m_getopt_table[option_idx].val;
|
|
|
|
switch (short_option) {
|
|
case 'f': {
|
|
m_file.assign(std::string(option_arg));
|
|
break;
|
|
}
|
|
case 't': {
|
|
int64_t thread_index;
|
|
if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) ||
|
|
thread_index < 0)
|
|
error.SetErrorStringWithFormat("invalid integer value for option '%s'",
|
|
option_arg.str().c_str());
|
|
else
|
|
m_thread_index = thread_index;
|
|
break;
|
|
}
|
|
default:
|
|
llvm_unreachable("Unimplemented option");
|
|
}
|
|
return error;
|
|
}
|
|
|
|
void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting(
|
|
ExecutionContext *execution_context) {
|
|
m_file.clear();
|
|
m_thread_index = None;
|
|
}
|
|
|
|
llvm::ArrayRef<OptionDefinition>
|
|
CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() {
|
|
return llvm::makeArrayRef(g_thread_trace_export_ctf_options);
|
|
}
|
|
|
|
bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
|
|
CommandReturnObject &result) {
|
|
const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
|
|
Process *process = m_exe_ctx.GetProcessPtr();
|
|
Thread *thread = m_options.m_thread_index
|
|
? process->GetThreadList()
|
|
.FindThreadByIndexID(*m_options.m_thread_index)
|
|
.get()
|
|
: GetDefaultThread();
|
|
|
|
if (thread == nullptr) {
|
|
const uint32_t num_threads = process->GetThreadList().GetSize();
|
|
size_t tid = m_options.m_thread_index ? *m_options.m_thread_index
|
|
: LLDB_INVALID_THREAD_ID;
|
|
result.AppendErrorWithFormat(
|
|
"Thread index %" PRIu64 " is out of range (valid values are 0 - %u).\n", tid,
|
|
num_threads);
|
|
return false;
|
|
} else {
|
|
TraceHTR htr(*thread, *trace_sp->GetCursor(*thread));
|
|
htr.ExecutePasses();
|
|
if (llvm::Error err = htr.Export(m_options.m_file)) {
|
|
result.AppendErrorWithFormat("%s\n", toString(std::move(err)).c_str());
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
}
|