summaryrefslogtreecommitdiff
path: root/tools/intel-features/intel-pt/cli-wrapper-pt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/intel-features/intel-pt/cli-wrapper-pt.cpp')
-rw-r--r--tools/intel-features/intel-pt/cli-wrapper-pt.cpp583
1 files changed, 0 insertions, 583 deletions
diff --git a/tools/intel-features/intel-pt/cli-wrapper-pt.cpp b/tools/intel-features/intel-pt/cli-wrapper-pt.cpp
deleted file mode 100644
index 1fa236cb0bc7..000000000000
--- a/tools/intel-features/intel-pt/cli-wrapper-pt.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-//===-- cli-wrapper-pt.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-// CLI Wrapper of PTDecoder Tool to enable it to be used through LLDB's CLI. The
-// wrapper provides a new command called processor-trace with 4 child
-// subcommands as follows:
-// processor-trace start
-// processor-trace stop
-// processor-trace show-trace-options
-// processor-trace show-instr-log
-//
-//===----------------------------------------------------------------------===//
-
-#include <cerrno>
-#include <cinttypes>
-#include <cstring>
-#include <string>
-#include <vector>
-
-#include "PTDecoder.h"
-#include "cli-wrapper-pt.h"
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBCommandReturnObject.h"
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBStructuredData.h"
-#include "lldb/API/SBTarget.h"
-#include "lldb/API/SBThread.h"
-
-static bool GetProcess(lldb::SBDebugger &debugger,
- lldb::SBCommandReturnObject &result,
- lldb::SBProcess &process) {
- if (!debugger.IsValid()) {
- result.Printf("error: invalid debugger\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- lldb::SBTarget target = debugger.GetSelectedTarget();
- if (!target.IsValid()) {
- result.Printf("error: invalid target inside debugger\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- process = target.GetProcess();
- if (!process.IsValid() ||
- (process.GetState() == lldb::StateType::eStateDetached) ||
- (process.GetState() == lldb::StateType::eStateExited) ||
- (process.GetState() == lldb::StateType::eStateInvalid)) {
- result.Printf("error: invalid process inside debugger's target\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- return true;
-}
-
-static bool ParseCommandOption(char **command,
- lldb::SBCommandReturnObject &result,
- uint32_t &index, const std::string &arg,
- uint32_t &parsed_result) {
- char *endptr;
- if (!command[++index]) {
- result.Printf("error: option \"%s\" requires an argument\n", arg.c_str());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- errno = 0;
- unsigned long output = strtoul(command[index], &endptr, 0);
- if ((errno != 0) || (*endptr != '\0')) {
- result.Printf("error: invalid value \"%s\" provided for option \"%s\"\n",
- command[index], arg.c_str());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- if (output > UINT32_MAX) {
- result.Printf("error: value \"%s\" for option \"%s\" exceeds UINT32_MAX\n",
- command[index], arg.c_str());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- parsed_result = (uint32_t)output;
- return true;
-}
-
-static bool ParseCommandArgThread(char **command,
- lldb::SBCommandReturnObject &result,
- lldb::SBProcess &process, uint32_t &index,
- lldb::tid_t &thread_id) {
- char *endptr;
- if (!strcmp(command[index], "all"))
- thread_id = LLDB_INVALID_THREAD_ID;
- else {
- uint32_t thread_index_id;
- errno = 0;
- unsigned long output = strtoul(command[index], &endptr, 0);
- if ((errno != 0) || (*endptr != '\0') || (output > UINT32_MAX)) {
- result.Printf("error: invalid thread specification: \"%s\"\n",
- command[index]);
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_index_id = (uint32_t)output;
-
- lldb::SBThread thread = process.GetThreadByIndexID(thread_index_id);
- if (!thread.IsValid()) {
- result.Printf(
- "error: process has no thread with thread specification: \"%s\"\n",
- command[index]);
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
- return true;
-}
-
-class ProcessorTraceStart : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceStart(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceStart() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- // Default initialize API's arguments
- lldb::SBTraceOptions lldb_SBTraceOptions;
- uint32_t trace_buffer_size = m_default_trace_buff_size;
- lldb::tid_t thread_id;
-
- // Parse Command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- if (!strcmp(command[i], "-b")) {
- if (!ParseCommandOption(command, result, i, "-b", trace_buffer_size))
- return false;
- } else {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- if (trace_buffer_size > m_max_trace_buff_size)
- trace_buffer_size = m_max_trace_buff_size;
-
- // Set API's arguments with parsed values
- lldb_SBTraceOptions.setType(lldb::TraceType::eTraceTypeProcessorTrace);
- lldb_SBTraceOptions.setTraceBufferSize(trace_buffer_size);
- lldb_SBTraceOptions.setMetaDataBufferSize(0);
- lldb_SBTraceOptions.setThreadID(thread_id);
- lldb::SBStream sb_stream;
- sb_stream.Printf("{\"trace-tech\":\"intel-pt\"}");
- lldb::SBStructuredData custom_params;
- lldb::SBError error = custom_params.SetFromJSON(sb_stream);
- if (!error.Success()) {
- result.Printf("error: %s\n", error.GetCString());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- lldb_SBTraceOptions.setTraceParams(custom_params);
-
- // Start trace
- pt_decoder_sp->StartProcessorTrace(process, lldb_SBTraceOptions, error);
- if (!error.Success()) {
- result.Printf("error: %s\n", error.GetCString());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
- const uint32_t m_max_trace_buff_size = 0x3fff;
- const uint32_t m_default_trace_buff_size = 4096;
-};
-
-class ProcessorTraceInfo : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceInfo(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceInfo() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- lldb::tid_t thread_id;
-
- // Parse command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- size_t loop_count = 1;
- bool entire_process_tracing = false;
- if (thread_id == LLDB_INVALID_THREAD_ID) {
- entire_process_tracing = true;
- loop_count = process.GetNumThreads();
- }
-
- // Get trace information
- lldb::SBError error;
- lldb::SBCommandReturnObject res;
- for (size_t i = 0; i < loop_count; i++) {
- error.Clear();
- res.Clear();
-
- if (entire_process_tracing)
- thread = process.GetThreadAtIndex(i);
- else
- thread = process.GetThreadByID(thread_id);
- thread_id = thread.GetThreadID();
-
- ptdecoder::PTTraceOptions options;
- pt_decoder_sp->GetProcessorTraceInfo(process, thread_id, options, error);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- lldb::SBStructuredData data = options.GetTraceParams(error);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- lldb::SBStream s;
- error = data.GetAsJSON(s);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64
- ", trace buffer size=%" PRIu64 ", meta buffer size=%" PRIu64
- ", trace type=%" PRIu32 ", custom trace params=%s",
- thread.GetIndexID(), thread_id, options.GetTraceBufferSize(),
- options.GetMetaDataBufferSize(), options.GetType(),
- s.GetData());
- result.AppendMessage(res.GetOutput());
- }
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
-};
-
-class ProcessorTraceShowInstrLog : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceShowInstrLog(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceShowInstrLog() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- // Default initialize API's arguments
- uint32_t offset;
- bool offset_provided = false;
- uint32_t count = m_default_count;
- lldb::tid_t thread_id;
-
- // Parse command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- if (!strcmp(command[i], "-o")) {
- if (!ParseCommandOption(command, result, i, "-o", offset))
- return false;
- offset_provided = true;
- } else if (!strcmp(command[i], "-c")) {
- if (!ParseCommandOption(command, result, i, "-c", count))
- return false;
- } else {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- size_t loop_count = 1;
- bool entire_process_tracing = false;
- if (thread_id == LLDB_INVALID_THREAD_ID) {
- entire_process_tracing = true;
- loop_count = process.GetNumThreads();
- }
-
- // Get instruction log and disassemble it
- lldb::SBError error;
- lldb::SBCommandReturnObject res;
- for (size_t i = 0; i < loop_count; i++) {
- error.Clear();
- res.Clear();
-
- if (entire_process_tracing)
- thread = process.GetThreadAtIndex(i);
- else
- thread = process.GetThreadByID(thread_id);
- thread_id = thread.GetThreadID();
-
- // If offset is not provided then calculate a default offset (to display
- // last 'count' number of instructions)
- if (!offset_provided)
- offset = count - 1;
-
- // Get the instruction log
- ptdecoder::PTInstructionList insn_list;
- pt_decoder_sp->GetInstructionLogAtOffset(process, thread_id, offset,
- count, insn_list, error);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- // Disassemble the instruction log
- std::string disassembler_command("dis -c 1 -s ");
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 "\n", thread.GetIndexID(),
- thread_id);
- lldb::SBCommandInterpreter sb_cmnd_interpreter(
- debugger.GetCommandInterpreter());
- lldb::SBCommandReturnObject result_obj;
- for (size_t i = 0; i < insn_list.GetSize(); i++) {
- ptdecoder::PTInstruction insn = insn_list.GetInstructionAtIndex(i);
- uint64_t addr = insn.GetInsnAddress();
- std::string error = insn.GetError();
- if (!error.empty()) {
- res.AppendMessage(error.c_str());
- continue;
- }
-
- result_obj.Clear();
- std::string complete_disassembler_command =
- disassembler_command + std::to_string(addr);
- sb_cmnd_interpreter.HandleCommand(complete_disassembler_command.c_str(),
- result_obj, false);
- std::string result_str(result_obj.GetOutput());
- if (result_str.empty()) {
- lldb::SBCommandReturnObject output;
- output.Printf(" Disassembly not found for address: %" PRIu64, addr);
- res.AppendMessage(output.GetOutput());
- continue;
- }
-
- // LLDB's disassemble command displays assembly instructions along with
- // the names of the functions they belong to. Parse this result to
- // display only the assembly instructions and not the function names
- // in an instruction log
- std::size_t first_new_line_index = result_str.find_first_of('\n');
- std::size_t last_new_line_index = result_str.find_last_of('\n');
- if (first_new_line_index != last_new_line_index)
- res.AppendMessage((result_str.substr(first_new_line_index + 1,
- last_new_line_index -
- first_new_line_index - 1))
- .c_str());
- else
- res.AppendMessage(
- (result_str.substr(0, result_str.length() - 1)).c_str());
- }
- result.AppendMessage(res.GetOutput());
- }
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
- const uint32_t m_default_count = 10;
-};
-
-class ProcessorTraceStop : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceStop(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceStop() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- lldb::tid_t thread_id;
-
- // Parse command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- // Stop trace
- lldb::SBError error;
- pt_decoder_sp->StopProcessorTrace(process, error, thread_id);
- if (!error.Success()) {
- result.Printf("error: %s\n", error.GetCString());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
-};
-
-bool PTPluginInitialize(lldb::SBDebugger &debugger) {
- lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
- lldb::SBCommand proc_trace = interpreter.AddMultiwordCommand(
- "processor-trace", "Intel(R) Processor Trace for thread/process");
-
- std::shared_ptr<ptdecoder::PTDecoder> PTDecoderSP(
- new ptdecoder::PTDecoder(debugger));
-
- lldb::SBCommandPluginInterface *proc_trace_start =
- new ProcessorTraceStart(PTDecoderSP);
- const char *help_proc_trace_start = "start Intel(R) Processor Trace on a "
- "specific thread or on the whole process";
- const char *syntax_proc_trace_start =
- "processor-trace start <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace start [-b <buffer-size>] [<thread-index>]\n\n"
- "\t\b-b <buffer-size>\n"
- "\t size of the trace buffer to store the trace data. If not "
- "specified then a default value will be taken\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to start tracing the whole process\n";
- proc_trace.AddCommand("start", proc_trace_start, help_proc_trace_start,
- syntax_proc_trace_start);
-
- lldb::SBCommandPluginInterface *proc_trace_stop =
- new ProcessorTraceStop(PTDecoderSP);
- const char *help_proc_trace_stop =
- "stop Intel(R) Processor Trace on a specific thread or on whole process";
- const char *syntax_proc_trace_stop =
- "processor-trace stop <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace stop [<thread-index>]\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to stop tracing the whole process\n";
- proc_trace.AddCommand("stop", proc_trace_stop, help_proc_trace_stop,
- syntax_proc_trace_stop);
-
- lldb::SBCommandPluginInterface *proc_trace_show_instr_log =
- new ProcessorTraceShowInstrLog(PTDecoderSP);
- const char *help_proc_trace_show_instr_log =
- "display a log of assembly instructions executed for a specific thread "
- "or for the whole process.\n"
- "The length of the log to be displayed and the offset in the whole "
- "instruction log from where the log needs to be displayed can also be "
- "provided. The offset is counted from the end of this whole "
- "instruction log which means the last executed instruction is at offset "
- "0 (zero)";
- const char *syntax_proc_trace_show_instr_log =
- "processor-trace show-instr-log <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace show-instr-log [-o <offset>] [-c <count>] "
- "[<thread-index>]\n\n"
- "\t\b-o <offset>\n"
- "\t offset in the whole instruction log from where the log will be "
- "displayed. If not specified then a default value will be taken\n\n"
- "\t\b-c <count>\n"
- "\t number of instructions to be displayed. If not specified then a "
- "default value will be taken\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to show instruction log for all the "
- "threads of the process\n";
- proc_trace.AddCommand("show-instr-log", proc_trace_show_instr_log,
- help_proc_trace_show_instr_log,
- syntax_proc_trace_show_instr_log);
-
- lldb::SBCommandPluginInterface *proc_trace_options =
- new ProcessorTraceInfo(PTDecoderSP);
- const char *help_proc_trace_show_options =
- "display all the information regarding Intel(R) Processor Trace for a "
- "specific thread or for the whole process.\n"
- "The information contains trace buffer size and configuration options"
- " of Intel(R) Processor Trace.";
- const char *syntax_proc_trace_show_options =
- "processor-trace show-options <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace show-options [<thread-index>]\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to display information for all threads "
- "of the process\n";
- proc_trace.AddCommand("show-trace-options", proc_trace_options,
- help_proc_trace_show_options,
- syntax_proc_trace_show_options);
-
- return true;
-}