LLDB  mainline
ThreadPlanTracer.cpp
Go to the documentation of this file.
1 //===-- ThreadPlanTracer.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 <cstring>
10 
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/Disassembler.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/StreamFile.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Symbol/TypeList.h"
18 #include "lldb/Symbol/TypeSystem.h"
19 #include "lldb/Target/ABI.h"
20 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Target/ThreadPlan.h"
28 #include "lldb/Utility/Log.h"
29 #include "lldb/Utility/State.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 #pragma mark ThreadPlanTracer
35 
36 ThreadPlanTracer::ThreadPlanTracer(Thread &thread, lldb::StreamSP &stream_sp)
37  : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()),
38  m_single_step(true), m_enabled(false), m_stream_sp(stream_sp) {}
39 
41  : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()),
42  m_single_step(true), m_enabled(false), m_stream_sp() {}
43 
45  if (m_stream_sp)
46  return m_stream_sp.get();
47  else {
48  TargetSP target_sp(GetThread().CalculateTarget());
49  if (target_sp)
50  return &(target_sp->GetDebugger().GetOutputStream());
51  }
52  return nullptr;
53 }
54 
56  if (m_thread)
57  return *m_thread;
58 
59  ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid);
60  m_thread = thread_sp.get();
61  return *m_thread;
62 }
64  SymbolContext sc;
65  bool show_frame_index = false;
66  bool show_fullpaths = false;
67 
68  Stream *stream = GetLogStream();
69  if (stream) {
70  GetThread().GetStackFrameAtIndex(0)->Dump(stream, show_frame_index,
71  show_fullpaths);
72  stream->Printf("\n");
73  stream->Flush();
74  }
75 }
76 
78  if (m_enabled && m_single_step) {
79  lldb::StopInfoSP stop_info = GetThread().GetStopInfo();
80  return (stop_info->GetStopReason() == eStopReasonTrace);
81  } else
82  return false;
83 }
84 
85 #pragma mark ThreadPlanAssemblyTracer
86 
88  lldb::StreamSP &stream_sp)
89  : ThreadPlanTracer(thread, stream_sp), m_disassembler_sp(), m_intptr_type(),
90  m_register_values() {}
91 
95 
97  if (!m_disassembler_sp)
99  m_process.GetTarget().GetArchitecture(), nullptr, nullptr);
100  return m_disassembler_sp.get();
101 }
102 
104  if (!m_intptr_type.IsValid()) {
105  if (auto target_sp = m_process.CalculateTarget()) {
106  auto type_system_or_err =
107  target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
108  if (auto err = type_system_or_err.takeError()) {
111  std::move(err),
112  "Unable to get integer pointer type from TypeSystem");
113  } else {
115  type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
117  target_sp->GetArchitecture().GetAddressByteSize() * 8));
118  }
119  }
120  }
121  return m_intptr_type;
122 }
123 
125 
127 }
128 
130 
132  Stream *stream = GetLogStream();
133 
134  if (!stream)
135  return;
136 
137  RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();
138 
139  lldb::addr_t pc = reg_ctx->GetPC();
140  Address pc_addr;
141  bool addr_valid = false;
142  uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
144  pc, pc_addr);
145 
148  stream->PutCString(" ");
149 
150  Disassembler *disassembler = GetDisassembler();
151  if (disassembler) {
152  Status err;
153  m_process.ReadMemory(pc, buffer, sizeof(buffer), err);
154 
155  if (err.Success()) {
156  DataExtractor extractor(buffer, sizeof(buffer), m_process.GetByteOrder(),
158 
159  bool data_from_file = false;
160  if (addr_valid)
161  disassembler->DecodeInstructions(pc_addr, extractor, 0, 1, false,
162  data_from_file);
163  else
164  disassembler->DecodeInstructions(Address(pc), extractor, 0, 1, false,
165  data_from_file);
166 
167  InstructionList &instruction_list = disassembler->GetInstructionList();
168  const uint32_t max_opcode_byte_size =
169  instruction_list.GetMaxOpcocdeByteSize();
170 
171  if (instruction_list.GetSize()) {
172  const bool show_bytes = true;
173  const bool show_address = true;
174  Instruction *instruction =
175  instruction_list.GetInstructionAtIndex(0).get();
176  const FormatEntity::Entry *disassemble_format =
178  instruction->Dump(stream, max_opcode_byte_size, show_address,
179  show_bytes, nullptr, nullptr, nullptr,
180  disassemble_format, 0);
181  }
182  }
183  }
184 
185  const ABI *abi = m_process.GetABI().get();
186  TypeFromUser intptr_type = GetIntPointerType();
187 
188  if (abi && intptr_type.IsValid()) {
189  ValueList value_list;
190  const int num_args = 1;
191 
192  for (int arg_index = 0; arg_index < num_args; ++arg_index) {
193  Value value;
195  value.SetCompilerType(intptr_type);
196  value_list.PushValue(value);
197  }
198 
199  if (abi->GetArgumentValues(GetThread(), value_list)) {
200  for (int arg_index = 0; arg_index < num_args; ++arg_index) {
201  stream->Printf(
202  "\n\targ[%d]=%llx", arg_index,
203  value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
204 
205  if (arg_index + 1 < num_args)
206  stream->PutCString(", ");
207  }
208  }
209  }
210 
211  if (m_register_values.empty()) {
212  RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();
213  m_register_values.resize(reg_ctx->GetRegisterCount());
214  }
215 
216  RegisterValue reg_value;
217  for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
218  reg_num < num_registers; ++reg_num) {
219  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
220  if (reg_ctx->ReadRegister(reg_info, reg_value)) {
221  assert(reg_num < m_register_values.size());
222  if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid ||
223  reg_value != m_register_values[reg_num]) {
224  if (reg_value.GetType() != RegisterValue::eTypeInvalid) {
225  stream->PutCString("\n\t");
226  DumpRegisterValue(reg_value, stream, reg_info, true, false,
228  }
229  }
230  m_register_values[reg_num] = reg_value;
231  }
232  }
233  stream->EOL();
234  stream->Flush();
235 }
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
An data extractor class.
Definition: DataExtractor.h:48
A class that represents a running process on the host machine.
const ArchSpec & GetArchitecture() const
Definition: Target.h:942
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
virtual void Dump(Stream *s, uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, const ExecutionContext *exe_ctx, const SymbolContext *sym_ctx, const SymbolContext *prev_sym_ctx, const FormatEntity::Entry *disassembly_addr_format, size_t max_address_text_size)
Dump the text representation of this Instruction to a Stream.
TaggedASTType< 1 > TypeFromUser
Definition: TaggedASTType.h:40
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX) const
Dump a description of this object to a Stream.
Definition: Address.cpp:392
ThreadList & GetThreadList()
Definition: Process.h:2068
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:705
void SetValueType(ValueType value_type)
Definition: Value.h:144
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3428
virtual void Flush()=0
Flush the stream.
virtual size_t DecodeInstructions(const Address &base_addr, const DataExtractor &data, lldb::offset_t data_offset, size_t num_instructions, bool append, bool data_from_file)=0
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:265
static lldb::DisassemblerSP FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name)
bool DumpRegisterValue(const RegisterValue &reg_val, Stream *s, const RegisterInfo *reg_info, bool prefix_with_name, bool prefix_with_alt_name, lldb::Format format, uint32_t reg_name_right_align_at=0)
virtual size_t GetRegisterCount()=0
lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update=true)
Definition: ThreadList.cpp:102
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
uint64_t GetPC(uint64_t fail_value=LLDB_INVALID_ADDRESS)
SectionLoadList & GetSectionLoadList()
Definition: Target.h:1013
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3432
const lldb::ABISP & GetABI()
Definition: Process.cpp:1582
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:618
virtual lldb::RegisterContextSP GetRegisterContext()=0
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, bool allow_section_end=false) const
unsigned integer
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
const FormatEntity::Entry * GetDisassemblyFormat() const
Definition: Debugger.cpp:246
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
RegisterValue::Type GetType() const
Definition: RegisterValue.h:81
bool Success() const
Test for success condition.
Definition: Status.cpp:288
std::vector< RegisterValue > m_register_values
A section + offset based address class.
Definition: Address.h:59
InstructionList & GetInstructionList()
virtual bool GetArgumentValues(Thread &thread, ValueList &values) const =0
ThreadPlanTracer(Thread &thread, lldb::StreamSP &stream_sp)
uint32_t GetMaxOpcocdeByteSize() const
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1210
Display the details about what an address resolves to.
Definition: Address.h:101
uint64_t addr_t
Definition: lldb-types.h:83
ThreadPlanAssemblyTracer(Thread &thread, lldb::StreamSP &stream_sp)
Non-standardized C, such as K&R.
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:62
Definition: SBAddress.h:15
Display as the file address with the module name prepended (if any).
Definition: Address.h:90
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:268
#define LIBLLDB_LOG_TYPES
Definition: Logging.h:33
const Scalar & GetScalar() const
Definition: Value.h:168
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:398
lldb::TargetSP CalculateTarget() override
Definition: Process.cpp:4291
lldb::StopInfoSP GetStopInfo()
Definition: Thread.cpp:339
Debugger & GetDebugger()
Definition: Target.h:975
An error handling class.
Definition: Status.h:44
void PushValue(const Value &value)
Definition: Value.cpp:701
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:2021