LLDB  mainline
LibStdcpp.cpp
Go to the documentation of this file.
1 //===-- LibStdcpp.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 "LibStdcpp.h"
10 
12 #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();
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  options.SetHasSourceSize(true);
263 
266  stream.Printf("Summary Unavailable");
267  return true;
268  } else
269  return true;
270  } break;
271  case eAddressTypeHost:
272  break;
273  case eAddressTypeInvalid:
274  case eAddressTypeFile:
275  break;
276  }
277  }
278  return false;
279 }
280 
282  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
283  const bool scalar_is_load_addr = true;
284  AddressType addr_type;
285  lldb::addr_t addr_of_string =
286  valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
287  if (addr_of_string != LLDB_INVALID_ADDRESS) {
288  switch (addr_type) {
289  case eAddressTypeLoad: {
290  ProcessSP process_sp(valobj.GetProcessSP());
291  if (!process_sp)
292  return false;
293 
294  CompilerType wchar_compiler_type =
296 
297  if (!wchar_compiler_type)
298  return false;
299 
300  // Safe to pass nullptr for exe_scope here.
301  llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
302  if (!size)
303  return false;
304  const uint32_t wchar_size = *size;
305 
307  Status error;
308  lldb::addr_t addr_of_data =
309  process_sp->ReadPointerFromMemory(addr_of_string, error);
310  if (error.Fail() || addr_of_data == 0 ||
311  addr_of_data == LLDB_INVALID_ADDRESS)
312  return false;
313  options.SetLocation(addr_of_data);
314  options.SetProcessSP(process_sp);
315  options.SetStream(&stream);
316  options.SetNeedsZeroTermination(false);
317  options.SetBinaryZeroIsTerminator(false);
318  lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
319  addr_of_string + process_sp->GetAddressByteSize(), error);
320  if (error.Fail())
321  return false;
322  options.SetSourceSize(size_of_data);
323  options.SetHasSourceSize(true);
324  options.SetPrefixToken("L");
325 
326  switch (wchar_size) {
327  case 8:
330  case 16:
333  case 32:
336  default:
337  stream.Printf("size for wchar_t is not valid");
338  return true;
339  }
340  return true;
341  } break;
342  case eAddressTypeHost:
343  break;
344  case eAddressTypeInvalid:
345  case eAddressTypeFile:
346  break;
347  }
348  }
349  return false;
350 }
351 
352 LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(
353  lldb::ValueObjectSP valobj_sp)
354  : SyntheticChildrenFrontEnd(*valobj_sp) {
355  if (valobj_sp)
356  Update();
357 }
358 
360 
361 lldb::ValueObjectSP
362 LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
363  ValueObjectSP valobj_sp = m_backend.GetSP();
364  if (!valobj_sp)
365  return lldb::ValueObjectSP();
366 
367  if (idx == 0)
368  return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true);
369  else
370  return lldb::ValueObjectSP();
371 }
372 
373 bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; }
374 
375 bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; }
376 
377 size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(
378  ConstString name) {
379  if (name == "_M_ptr")
380  return 0;
381  return UINT32_MAX;
382 }
383 
386  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
387  return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp)
388  : nullptr);
389 }
390 
392  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
393  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
394  if (!valobj_sp)
395  return false;
396 
397  ValueObjectSP ptr_sp(
398  valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true));
399  if (!ptr_sp)
400  return false;
401 
402  ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath(
403  {ConstString("_M_refcount"), ConstString("_M_pi"),
404  ConstString("_M_use_count")}));
405  if (!usecount_sp)
406  return false;
407 
408  if (ptr_sp->GetValueAsUnsigned(0) == 0 ||
409  usecount_sp->GetValueAsUnsigned(0) == 0) {
410  stream.Printf("nullptr");
411  return true;
412  }
413 
414  Status error;
415  ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
416  if (pointee_sp && error.Success()) {
417  if (pointee_sp->DumpPrintableRepresentation(
421  false)) {
422  return true;
423  }
424  }
425 
426  stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
427  return true;
428 }
CompilerType GetCompilerType()
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibStdcpp.cpp:225
A class that represents a running process on the host machine.
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:281
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
Create related types using the current type&#39;s AST.
bool LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:391
SyntheticChildrenFrontEnd * LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:385
#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:288
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:169
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:40
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
llvm::Optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
lldb::ProcessSP GetProcessSP() const
Definition: ValueObject.h:339
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: LibStdcpp.cpp:217
Definition: SBAddress.h:15
Represents a generic type in a programming language.
Definition: CompilerType.h:33
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:539
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.