LLDB  mainline
LibStdcpp.cpp
Go to the documentation of this file.
1 //===-- LibStdcpp.cpp -------------------------------------------*- 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 #include "LibStdcpp.h"
10 
11 #include "lldb/Core/ValueObject.h"
16 #include "lldb/Target/Target.h"
18 #include "lldb/Utility/Endian.h"
19 #include "lldb/Utility/Status.h"
20 #include "lldb/Utility/Stream.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 using namespace lldb_private::formatters;
25 
26 namespace {
27 
28 class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
29  /*
30  (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char,
31  std::char_traits<char>, std::allocator<char> > > >) ibeg = {
32  (_Base_ptr) _M_node = 0x0000000100103910 {
33  (std::_Rb_tree_color) _M_color = _S_black
34  (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
35  (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
36  (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
37  }
38  }
39  */
40 
41 public:
42  explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
43 
44  size_t CalculateNumChildren() override;
45 
46  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
47 
48  bool Update() override;
49 
50  bool MightHaveChildren() override;
51 
52  size_t GetIndexOfChildWithName(ConstString name) override;
53 
54 private:
55  ExecutionContextRef m_exe_ctx_ref;
56  lldb::addr_t m_pair_address;
57  CompilerType m_pair_type;
58  lldb::ValueObjectSP m_pair_sp;
59 };
60 
61 class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
62 public:
63  explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
64 
65  size_t CalculateNumChildren() override;
66 
67  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
68 
69  bool Update() override;
70 
71  bool MightHaveChildren() override;
72 
73  size_t GetIndexOfChildWithName(ConstString name) override;
74 };
75 
76 } // end of anonymous namespace
77 
78 LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd(
79  lldb::ValueObjectSP valobj_sp)
80  : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_address(0),
81  m_pair_type(), m_pair_sp() {
82  if (valobj_sp)
83  Update();
84 }
85 
86 bool LibstdcppMapIteratorSyntheticFrontEnd::Update() {
87  ValueObjectSP valobj_sp = m_backend.GetSP();
88  if (!valobj_sp)
89  return false;
90 
91  TargetSP target_sp(valobj_sp->GetTargetSP());
92 
93  if (!target_sp)
94  return false;
95 
96  bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8);
97 
98  if (!valobj_sp)
99  return false;
100  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
101 
102  ValueObjectSP _M_node_sp(
103  valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true));
104  if (!_M_node_sp)
105  return false;
106 
107  m_pair_address = _M_node_sp->GetValueAsUnsigned(0);
108  if (m_pair_address == 0)
109  return false;
110 
111  m_pair_address += (is_64bit ? 32 : 16);
112 
113  CompilerType my_type(valobj_sp->GetCompilerType());
114  if (my_type.GetNumTemplateArguments() >= 1) {
115  CompilerType pair_type = my_type.GetTypeTemplateArgument(0);
116  if (!pair_type)
117  return false;
118  m_pair_type = pair_type;
119  } else
120  return false;
121 
122  return true;
123 }
124 
126  return 2;
127 }
128 
129 lldb::ValueObjectSP
130 LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
131  if (m_pair_address != 0 && m_pair_type) {
132  if (!m_pair_sp)
133  m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address,
134  m_exe_ctx_ref, m_pair_type);
135  if (m_pair_sp)
136  return m_pair_sp->GetChildAtIndex(idx, true);
137  }
138  return lldb::ValueObjectSP();
139 }
140 
141 bool LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren() { return true; }
142 
143 size_t LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName(
144  ConstString name) {
145  if (name == "first")
146  return 0;
147  if (name == "second")
148  return 1;
149  return UINT32_MAX;
150 }
151 
154  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
155  return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp)
156  : nullptr);
157 }
158 
159 /*
160  (lldb) fr var ibeg --ptr-depth 1
161  (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >)
162  ibeg = {
163  _M_current = 0x00000001001037a0 {
164  *_M_current = 1
165  }
166  }
167  */
168 
171  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
172  static ConstString g_item_name;
173  if (!g_item_name)
174  g_item_name.SetCString("_M_current");
175  return (valobj_sp
176  ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name)
177  : nullptr);
178 }
179 
181  VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp,
182  ConstString item_name)
183  : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(),
184  m_item_name(item_name), m_item_sp() {
185  if (valobj_sp)
186  Update();
187 }
188 
190  m_item_sp.reset();
191 
192  ValueObjectSP valobj_sp = m_backend.GetSP();
193  if (!valobj_sp)
194  return false;
195 
196  if (!valobj_sp)
197  return false;
198 
199  ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name, true));
200  if (!item_ptr)
201  return false;
202  if (item_ptr->GetValueAsUnsigned(0) == 0)
203  return false;
204  Status err;
205  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
206  m_item_sp = CreateValueObjectFromAddress(
207  "item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref,
208  item_ptr->GetCompilerType().GetPointeeType());
209  if (err.Fail())
210  m_item_sp.reset();
211  return false;
212 }
213 
215 
216 lldb::ValueObjectSP
218  if (idx == 0)
219  return m_item_sp;
220  return lldb::ValueObjectSP();
221 }
222 
224 
226  ConstString name) {
227  if (name == "item")
228  return 0;
229  return UINT32_MAX;
230 }
231 
233  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
234  const bool scalar_is_load_addr = true;
235  AddressType addr_type;
236  lldb::addr_t addr_of_string =
237  valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
238  if (addr_of_string != LLDB_INVALID_ADDRESS) {
239  switch (addr_type) {
240  case eAddressTypeLoad: {
241  ProcessSP process_sp(valobj.GetProcessSP());
242  if (!process_sp)
243  return false;
244 
246  Status error;
247  lldb::addr_t addr_of_data =
248  process_sp->ReadPointerFromMemory(addr_of_string, error);
249  if (error.Fail() || addr_of_data == 0 ||
250  addr_of_data == LLDB_INVALID_ADDRESS)
251  return false;
252  options.SetLocation(addr_of_data);
253  options.SetProcessSP(process_sp);
254  options.SetStream(&stream);
255  options.SetNeedsZeroTermination(false);
256  options.SetBinaryZeroIsTerminator(true);
257  lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
258  addr_of_string + process_sp->GetAddressByteSize(), error);
259  if (error.Fail())
260  return false;
261  options.SetSourceSize(size_of_data);
262 
265  stream.Printf("Summary Unavailable");
266  return true;
267  } else
268  return true;
269  } break;
270  case eAddressTypeHost:
271  break;
272  case eAddressTypeInvalid:
273  case eAddressTypeFile:
274  break;
275  }
276  }
277  return false;
278 }
279 
281  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
282  const bool scalar_is_load_addr = true;
283  AddressType addr_type;
284  lldb::addr_t addr_of_string =
285  valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
286  if (addr_of_string != LLDB_INVALID_ADDRESS) {
287  switch (addr_type) {
288  case eAddressTypeLoad: {
289  ProcessSP process_sp(valobj.GetProcessSP());
290  if (!process_sp)
291  return false;
292 
293  CompilerType wchar_compiler_type =
295 
296  if (!wchar_compiler_type)
297  return false;
298 
299  // Safe to pass nullptr for exe_scope here.
300  llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
301  if (!size)
302  return false;
303  const uint32_t wchar_size = *size;
304 
306  Status error;
307  lldb::addr_t addr_of_data =
308  process_sp->ReadPointerFromMemory(addr_of_string, error);
309  if (error.Fail() || addr_of_data == 0 ||
310  addr_of_data == LLDB_INVALID_ADDRESS)
311  return false;
312  options.SetLocation(addr_of_data);
313  options.SetProcessSP(process_sp);
314  options.SetStream(&stream);
315  options.SetNeedsZeroTermination(false);
316  options.SetBinaryZeroIsTerminator(false);
317  lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
318  addr_of_string + process_sp->GetAddressByteSize(), error);
319  if (error.Fail())
320  return false;
321  options.SetSourceSize(size_of_data);
322  options.SetPrefixToken("L");
323 
324  switch (wchar_size) {
325  case 8:
328  case 16:
331  case 32:
334  default:
335  stream.Printf("size for wchar_t is not valid");
336  return true;
337  }
338  return true;
339  } break;
340  case eAddressTypeHost:
341  break;
342  case eAddressTypeInvalid:
343  case eAddressTypeFile:
344  break;
345  }
346  }
347  return false;
348 }
349 
350 LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(
351  lldb::ValueObjectSP valobj_sp)
352  : SyntheticChildrenFrontEnd(*valobj_sp) {
353  if (valobj_sp)
354  Update();
355 }
356 
358 
359 lldb::ValueObjectSP
360 LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
361  ValueObjectSP valobj_sp = m_backend.GetSP();
362  if (!valobj_sp)
363  return lldb::ValueObjectSP();
364 
365  if (idx == 0)
366  return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true);
367  else
368  return lldb::ValueObjectSP();
369 }
370 
371 bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; }
372 
373 bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; }
374 
375 size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(
376  ConstString name) {
377  if (name == "_M_ptr")
378  return 0;
379  return UINT32_MAX;
380 }
381 
384  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
385  return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp)
386  : nullptr);
387 }
388 
390  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
391  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
392  if (!valobj_sp)
393  return false;
394 
395  ValueObjectSP ptr_sp(
396  valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true));
397  if (!ptr_sp)
398  return false;
399 
400  ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath(
401  {ConstString("_M_refcount"), ConstString("_M_pi"),
402  ConstString("_M_use_count")}));
403  if (!usecount_sp)
404  return false;
405 
406  if (ptr_sp->GetValueAsUnsigned(0) == 0 ||
407  usecount_sp->GetValueAsUnsigned(0) == 0) {
408  stream.Printf("nullptr");
409  return true;
410  }
411 
412  Status error;
413  ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
414  if (pointee_sp && error.Success()) {
415  if (pointee_sp->DumpPrintableRepresentation(
419  false)) {
420  return true;
421  }
422  }
423 
424  stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
425  return true;
426 }
CompilerType GetCompilerType()
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibStdcpp.cpp:225
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
Address is an address as found in an object or symbol file.
SyntheticChildrenFrontEnd * LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:170
bool LibStdcppWStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:280
bool LibStdcppStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:232
VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp, ConstString item_name)
Definition: LibStdcpp.cpp:181
static bool ReadStringAndDumpToStream(const ReadStringAndDumpToStreamOptions &options)
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
bool LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:389
SyntheticChildrenFrontEnd * LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:383
#define UINT32_MAX
Definition: lldb-defines.h:31
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
Address is an address in the process that is running this code.
virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address=true, AddressType *address_type=nullptr)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:287
Execution context objects refer to objects in the execution of the program that is being debugged...
SyntheticChildrenFrontEnd(ValueObject &backend)
Definition: TypeSynthetic.h:36
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:168
uint64_t addr_t
Definition: lldb-types.h:83
lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type)
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
llvm::Optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
lldb::ProcessSP GetProcessSP() const
Definition: ValueObject.h:361
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: LibStdcpp.cpp:217
Definition: SBAddress.h:15
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:565
CompilerType GetTypeTemplateArgument(size_t idx) const
SyntheticChildrenFrontEnd * LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:153
Address is an address as in the current target inferior process.
virtual lldb::ValueObjectSP GetNonSyntheticValue()
An error handling class.
Definition: Status.h:44
void SetCString(const char *cstr)
Set the C string value.