LLDB  mainline
DecodedThread.h
Go to the documentation of this file.
1 //===-- DecodedThread.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H
10 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H
11 
12 #include <vector>
13 
14 #include "llvm/Support/Errc.h"
15 #include "llvm/Support/Error.h"
16 
17 #include "lldb/Target/Trace.h"
19 
20 #include "intel-pt.h"
21 
22 namespace lldb_private {
23 namespace trace_intel_pt {
24 
25 /// Class for representing a libipt decoding error.
26 class IntelPTError : public llvm::ErrorInfo<IntelPTError> {
27 public:
28  static char ID;
29 
30  /// \param[in] libipt_error_code
31  /// Negative number returned by libipt when decoding the trace and
32  /// signaling errors.
33  ///
34  /// \param[in] address
35  /// Optional instruction address. When decoding an individual instruction,
36  /// its address might be available in the \a pt_insn object, and should be
37  /// passed to this constructor. Other errors don't have an associated
38  /// address.
39  IntelPTError(int libipt_error_code,
41 
42  std::error_code convertToErrorCode() const override {
43  return llvm::errc::not_supported;
44  }
45 
46  void log(llvm::raw_ostream &OS) const override;
47 
48 private:
51 };
52 
53 /// \class IntelPTInstruction
54 /// An instruction obtained from decoding a trace. It is either an actual
55 /// instruction or an error indicating a gap in the trace.
56 ///
57 /// Gaps in the trace can come in a few flavors:
58 /// - tracing gaps (e.g. tracing was paused and then resumed)
59 /// - tracing errors (e.g. buffer overflow)
60 /// - decoding errors (e.g. some memory region couldn't be decoded)
61 /// As mentioned, any gap is represented as an error in this class.
63 public:
64  IntelPTInstruction(const pt_insn &pt_insn, uint64_t timestamp)
65  : m_pt_insn(pt_insn), m_timestamp(timestamp) {}
66 
67  IntelPTInstruction(const pt_insn &pt_insn) : m_pt_insn(pt_insn) {}
68 
69  /// Error constructor
70  ///
71  /// libipt errors should use the underlying \a IntelPTError class.
73 
74  /// Check if this object represents an error (i.e. a gap).
75  ///
76  /// \return
77  /// Whether this object represents an error.
78  bool IsError() const;
79 
80  /// \return
81  /// The instruction pointer address, or \a LLDB_INVALID_ADDRESS if it is
82  /// an error.
84 
85  /// \return
86  /// An \a llvm::Error object if this class corresponds to an Error, or an
87  /// \a llvm::Error::success otherwise.
88  llvm::Error ToError() const;
89 
90  /// Get the timestamp associated with the current instruction. The timestamp
91  /// is similar to what a rdtsc instruction would return.
92  ///
93  /// \return
94  /// The timestamp or \b llvm::None if not available.
95  llvm::Optional<uint64_t> GetTimestampCounter() const;
96 
97  /// Get the \a lldb::TraceInstructionControlFlowType categories of the
98  /// instruction.
99  ///
100  /// \param[in] next_load_address
101  /// The address of the next instruction in the trace or \b
102  /// LLDB_INVALID_ADDRESS if not available.
103  ///
104  /// \return
105  /// The control flow categories, or \b 0 if the instruction is an error.
106  lldb::TraceInstructionControlFlowType
107  GetControlFlowType(lldb::addr_t next_load_address) const;
108 
109  IntelPTInstruction(IntelPTInstruction &&other) = default;
110 
111 private:
112  IntelPTInstruction(const IntelPTInstruction &other) = delete;
113  const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete;
114 
115  pt_insn m_pt_insn;
116  llvm::Optional<uint64_t> m_timestamp;
117  std::unique_ptr<llvm::ErrorInfoBase> m_error;
118 };
119 
120 /// \class DecodedThread
121 /// Class holding the instructions and function call hierarchy obtained from
122 /// decoding a trace, as well as a position cursor used when reverse debugging
123 /// the trace.
124 ///
125 /// Each decoded thread contains a cursor to the current position the user is
126 /// stopped at. See \a Trace::GetCursorPosition for more information.
127 class DecodedThread : public std::enable_shared_from_this<DecodedThread> {
128 public:
129  DecodedThread(lldb::ThreadSP thread_sp,
130  std::vector<IntelPTInstruction> &&instructions,
131  size_t raw_trace_size);
132 
133  /// Constructor with a single error signaling a complete failure of the
134  /// decoding process.
135  DecodedThread(lldb::ThreadSP thread_sp, llvm::Error error);
136 
137  /// Get the instructions from the decoded trace. Some of them might indicate
138  /// errors (i.e. gaps) in the trace.
139  ///
140  /// \return
141  /// The instructions of the trace.
142  llvm::ArrayRef<IntelPTInstruction> GetInstructions() const;
143 
144  /// Get a new cursor for the decoded thread.
145  lldb::TraceCursorUP GetCursor();
146 
147  /// Get the size in bytes of the corresponding Intel PT raw trace
148  ///
149  /// \return
150  /// The size of the trace.
151  size_t GetRawTraceSize() const;
152 
153 private:
154  lldb::ThreadSP m_thread_sp;
155  std::vector<IntelPTInstruction> m_instructions;
157 };
158 
159 using DecodedThreadSP = std::shared_ptr<DecodedThread>;
160 
161 } // namespace trace_intel_pt
162 } // namespace lldb_private
163 
164 #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H
lldb_private::trace_intel_pt::IntelPTError::ID
static char ID
Definition: DecodedThread.h:28
lldb_private::trace_intel_pt::IntelPTInstruction::ToError
llvm::Error ToError() const
Definition: DecodedThread.cpp:55
lldb_private::trace_intel_pt::DecodedThread::GetCursor
lldb::TraceCursorUP GetCursor()
Get a new cursor for the decoded thread.
Definition: DecodedThread.cpp:116
lldb_private::trace_intel_pt::DecodedThread::m_raw_trace_size
size_t m_raw_trace_size
Definition: DecodedThread.h:156
lldb_private::trace_intel_pt::IntelPTError::m_libipt_error_code
int m_libipt_error_code
Definition: DecodedThread.h:49
lldb_private::trace_intel_pt::DecodedThread::DecodedThread
DecodedThread(lldb::ThreadSP thread_sp, std::vector< IntelPTInstruction > &&instructions, size_t raw_trace_size)
lldb_private::trace_intel_pt::IntelPTError::m_address
lldb::addr_t m_address
Definition: DecodedThread.h:50
lldb_private::trace_intel_pt::IntelPTInstruction::IsError
bool IsError() const
Check if this object represents an error (i.e.
Definition: DecodedThread.cpp:47
Trace.h
lldb_private::trace_intel_pt::IntelPTInstruction::GetControlFlowType
lldb::TraceInstructionControlFlowType GetControlFlowType(lldb::addr_t next_load_address) const
Get the lldb::TraceInstructionControlFlowType categories of the instruction.
Definition: DecodedThread.cpp:67
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::trace_intel_pt::IntelPTInstruction::m_pt_insn
pt_insn m_pt_insn
Definition: DecodedThread.h:115
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::trace_intel_pt::IntelPTError::IntelPTError
IntelPTError(int libipt_error_code, lldb::addr_t address=LLDB_INVALID_ADDRESS)
Definition: DecodedThread.cpp:24
lldb_private::trace_intel_pt::IntelPTInstruction::operator=
const IntelPTInstruction & operator=(const IntelPTInstruction &other)=delete
TraceIntelPTGDBRemotePackets.h
lldb_private::trace_intel_pt::IntelPTError::convertToErrorCode
std::error_code convertToErrorCode() const override
Definition: DecodedThread.h:42
lldb_private::trace_intel_pt::IntelPTInstruction::GetTimestampCounter
llvm::Optional< uint64_t > GetTimestampCounter() const
Get the timestamp associated with the current instruction.
Definition: DecodedThread.cpp:51
lldb_private::trace_intel_pt::IntelPTInstruction::IntelPTInstruction
IntelPTInstruction(const pt_insn &pt_insn)
Definition: DecodedThread.h:67
lldb_private::trace_intel_pt::DecodedThread::m_instructions
std::vector< IntelPTInstruction > m_instructions
Definition: DecodedThread.h:155
lldb_private::trace_intel_pt::IntelPTError
Class for representing a libipt decoding error.
Definition: DecodedThread.h:26
lldb_private::trace_intel_pt::IntelPTError::log
void log(llvm::raw_ostream &OS) const override
Definition: DecodedThread.cpp:29
lldb_private::trace_intel_pt::IntelPTInstruction::m_error
std::unique_ptr< llvm::ErrorInfoBase > m_error
Definition: DecodedThread.h:117
lldb_private::trace_intel_pt::IntelPTInstruction
Definition: DecodedThread.h:62
lldb_private::trace_intel_pt::DecodedThread::m_thread_sp
lldb::ThreadSP m_thread_sp
Definition: DecodedThread.h:154
lldb_private::trace_intel_pt::DecodedThread::GetRawTraceSize
size_t GetRawTraceSize() const
Get the size in bytes of the corresponding Intel PT raw trace.
Definition: DecodedThread.cpp:64
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:86
lldb_private::trace_intel_pt::DecodedThreadSP
std::shared_ptr< DecodedThread > DecodedThreadSP
Definition: DecodedThread.h:159
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
lldb_private::trace_intel_pt::DecodedThread
Definition: DecodedThread.h:127
lldb_private::trace_intel_pt::IntelPTInstruction::m_timestamp
llvm::Optional< uint64_t > m_timestamp
Definition: DecodedThread.h:116
lldb_private::trace_intel_pt::IntelPTInstruction::GetLoadAddress
lldb::addr_t GetLoadAddress() const
Definition: DecodedThread.cpp:49
lldb_private::trace_intel_pt::IntelPTInstruction::IntelPTInstruction
IntelPTInstruction(const pt_insn &pt_insn, uint64_t timestamp)
Definition: DecodedThread.h:64
lldb_private::trace_intel_pt::DecodedThread::GetInstructions
llvm::ArrayRef< IntelPTInstruction > GetInstructions() const
Get the instructions from the decoded trace.
Definition: DecodedThread.cpp:97