[trace][intel-pt] Implement the basic decoding functionality
authorWalter Erquinigo <wallace@fb.com>
Wed, 14 Oct 2020 17:26:10 +0000 (10:26 -0700)
committerWalter Erquinigo <a20012251@gmail.com>
Fri, 6 Nov 2020 02:38:03 +0000 (18:38 -0800)
commitcfd96f057ba4256fef49518cad43d0a7f591da12
treeb42ddff84e7d7250217b020716dbd82331781af0
parentb8745751f167f16717d36867ca46328afa4b7919
[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
31 files changed:
lldb/include/lldb/Core/Disassembler.h
lldb/include/lldb/Symbol/SymbolContext.h
lldb/include/lldb/Target/Trace.h
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Commands/CommandObjectThread.cpp
lldb/source/Commands/Options.td
lldb/source/Core/Disassembler.cpp
lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp [new file with mode: 0644]
lldb/source/Plugins/Trace/intel-pt/DecodedThread.h [new file with mode: 0644]
lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp [new file with mode: 0644]
lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h [new file with mode: 0644]
lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
lldb/source/Symbol/SymbolContext.cpp
lldb/source/Target/ProcessTrace.cpp
lldb/source/Target/Trace.cpp
lldb/source/Target/TraceSessionFileParser.cpp
lldb/test/API/commands/trace/TestTraceDumpInstructions.py
lldb/test/API/commands/trace/intelpt-trace-multi-file/a.out [new file with mode: 0755]
lldb/test/API/commands/trace/intelpt-trace-multi-file/bar.cpp [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace-multi-file/bar.h [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace-multi-file/foo.cpp [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace-multi-file/foo.h [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace-multi-file/libbar.so [new file with mode: 0755]
lldb/test/API/commands/trace/intelpt-trace-multi-file/libfoo.so [new file with mode: 0755]
lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace-multi-file/multi-file-no-ld.json [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace-multi-file/multi-file.trace [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace/trace_bad_image.json [new file with mode: 0644]
lldb/test/API/commands/trace/intelpt-trace/trace_wrong_cpu.json [new file with mode: 0644]