LLDB  mainline
DecodedThread.cpp
Go to the documentation of this file.
1 //===-- DecodedThread.cpp -------------------------------------------------===//
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 #include "DecodedThread.h"
10 
11 #include <intel-pt.h>
12 #include <memory>
13 
14 #include "TraceCursorIntelPT.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 using namespace lldb_private::trace_intel_pt;
20 using namespace llvm;
21 
22 char IntelPTError::ID;
23 
24 IntelPTError::IntelPTError(int libipt_error_code, lldb::addr_t address)
25  : m_libipt_error_code(libipt_error_code), m_address(address) {
26  assert(libipt_error_code < 0);
27 }
28 
29 void IntelPTError::log(llvm::raw_ostream &OS) const {
30  const char *libipt_error_message = pt_errstr(pt_errcode(m_libipt_error_code));
32  write_hex(OS, m_address, HexPrintStyle::PrefixLower, 18);
33  OS << " ";
34  }
35  OS << "error: " << libipt_error_message;
36 }
37 
39  llvm::handleAllErrors(std::move(err),
40  [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
41  m_error = std::move(info);
42  });
44  m_pt_insn.iclass = ptic_error;
45 }
46 
47 bool IntelPTInstruction::IsError() const { return (bool)m_error; }
48 
50 
51 Optional<uint64_t> IntelPTInstruction::GetTimestampCounter() const {
52  return m_timestamp;
53 }
54 
56  if (!IsError())
57  return Error::success();
58 
59  if (m_error->isA<IntelPTError>())
60  return make_error<IntelPTError>(static_cast<IntelPTError &>(*m_error));
61  return make_error<StringError>(m_error->message(),
62  m_error->convertToErrorCode());
63 }
65 
66 TraceInstructionControlFlowType
68  if (IsError())
69  return (TraceInstructionControlFlowType)0;
70 
71  TraceInstructionControlFlowType mask =
72  eTraceInstructionControlFlowTypeInstruction;
73 
74  switch (m_pt_insn.iclass) {
75  case ptic_cond_jump:
76  case ptic_jump:
77  case ptic_far_jump:
78  mask |= eTraceInstructionControlFlowTypeBranch;
79  if (m_pt_insn.ip + m_pt_insn.size != next_load_address)
80  mask |= eTraceInstructionControlFlowTypeTakenBranch;
81  break;
82  case ptic_return:
83  case ptic_far_return:
84  mask |= eTraceInstructionControlFlowTypeReturn;
85  break;
86  case ptic_call:
87  case ptic_far_call:
88  mask |= eTraceInstructionControlFlowTypeCall;
89  break;
90  default:
91  break;
92  }
93 
94  return mask;
95 }
96 
97 ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const {
98  return makeArrayRef(m_instructions);
99 }
100 
101 DecodedThread::DecodedThread(ThreadSP thread_sp, Error error)
102  : m_thread_sp(thread_sp) {
103  m_instructions.emplace_back(std::move(error));
104 }
105 
106 DecodedThread::DecodedThread(ThreadSP thread_sp,
107  std::vector<IntelPTInstruction> &&instructions,
108  size_t raw_trace_size)
109  : m_thread_sp(thread_sp), m_instructions(std::move(instructions)),
110  m_raw_trace_size(raw_trace_size) {
111  if (m_instructions.empty())
112  m_instructions.emplace_back(
113  createStringError(inconvertibleErrorCode(), "empty trace"));
114 }
115 
116 lldb::TraceCursorUP DecodedThread::GetCursor() {
117  return std::make_unique<TraceCursorIntelPT>(m_thread_sp, shared_from_this());
118 }
llvm
Definition: Debugger.h:49
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
TraceCursorIntelPT.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
ID
static char ID
Definition: IRDynamicChecks.cpp:32
DecodedThread.h
StreamString.h
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::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::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
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
Definition: CommandObjectTraceStartIntelPT.h:18
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
Definition: SBAddress.h:15
lldb_private::trace_intel_pt::DecodedThread::GetInstructions
llvm::ArrayRef< IntelPTInstruction > GetInstructions() const
Get the instructions from the decoded trace.
Definition: DecodedThread.cpp:97