LLDB  mainline
CPPLanguageRuntime.cpp
Go to the documentation of this file.
1 //===-- CPPLanguageRuntime.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 <memory>
12 
13 #include "CPPLanguageRuntime.h"
14 
15 #include "llvm/ADT/StringRef.h"
16 
17 #include "lldb/Symbol/Block.h"
18 #include "lldb/Symbol/Variable.h"
20 
24 #include "lldb/Target/ABI.h"
28 #include "lldb/Target/StackFrame.h"
31 #include "lldb/Utility/Timer.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 static ConstString g_this = ConstString("this");
37 
38 char CPPLanguageRuntime::ID = 0;
39 
40 CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
41  : LanguageRuntime(process) {}
42 
44  return name == g_this;
45 }
46 
48  ValueObject &object) {
49  // C++ has no generic way to do this.
50  return false;
51 }
52 
54  Stream &str, Value &value, ExecutionContextScope *exe_scope) {
55  // C++ has no generic way to do this.
56  return false;
57 }
58 
59 bool contains_lambda_identifier(llvm::StringRef &str_ref) {
60  return str_ref.contains("$_") || str_ref.contains("'lambda'");
61 }
62 
64 line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol,
65  llvm::StringRef first_template_param_sref,
66  bool has___invoke) {
67 
69 
70  AddressRange range;
71  sc.GetAddressRange(eSymbolContextEverything, 0, false, range);
72 
73  Address address = range.GetBaseAddress();
74 
75  Address addr;
76  if (target.ResolveLoadAddress(address.GetCallableLoadAddress(&target),
77  addr)) {
78  LineEntry line_entry;
79  addr.CalculateSymbolContextLineEntry(line_entry);
80 
81  if (contains_lambda_identifier(first_template_param_sref) || has___invoke) {
82  // Case 1 and 2
85  } else {
86  // Case 3
89  }
90 
91  optional_info.callable_symbol = *symbol;
92  optional_info.callable_line_entry = line_entry;
93  optional_info.callable_address = addr;
94  }
95 
96  return optional_info;
97 }
98 
101  lldb::ValueObjectSP &valobj_sp) {
103 
104  LibCppStdFunctionCallableInfo optional_info;
105 
106  if (!valobj_sp)
107  return optional_info;
108 
109  // Member __f_ has type __base*, the contents of which will hold:
110  // 1) a vtable entry which may hold type information needed to discover the
111  // lambda being called
112  // 2) possibly hold a pointer to the callable object
113  // e.g.
114  //
115  // (lldb) frame var -R f_display
116  // (std::__1::function<void (int)>) f_display = {
117  // __buf_ = {
118  // …
119  // }
120  // __f_ = 0x00007ffeefbffa00
121  // }
122  // (lldb) memory read -fA 0x00007ffeefbffa00
123  // 0x7ffeefbffa00: ... `vtable for std::__1::__function::__func<void (*) ...
124  // 0x7ffeefbffa08: ... `print_num(int) at std_function_cppreference_exam ...
125  //
126  // We will be handling five cases below, std::function is wrapping:
127  //
128  // 1) a lambda we know at compile time. We will obtain the name of the lambda
129  // from the first template pameter from __func's vtable. We will look up
130  // the lambda's operator()() and obtain the line table entry.
131  // 2) a lambda we know at runtime. A pointer to the lambdas __invoke method
132  // will be stored after the vtable. We will obtain the lambdas name from
133  // this entry and lookup operator()() and obtain the line table entry.
134  // 3) a callable object via operator()(). We will obtain the name of the
135  // object from the first template parameter from __func's vtable. We will
136  // look up the objects operator()() and obtain the line table entry.
137  // 4) a member function. A pointer to the function will stored after the
138  // we will obtain the name from this pointer.
139  // 5) a free function. A pointer to the function will stored after the vtable
140  // we will obtain the name from this pointer.
141  ValueObjectSP member__f_(
142  valobj_sp->GetChildMemberWithName(ConstString("__f_"), true));
143 
144  if (member__f_) {
145  ValueObjectSP sub_member__f_(
146  member__f_->GetChildMemberWithName(ConstString("__f_"), true));
147 
148  if (sub_member__f_)
149  member__f_ = sub_member__f_;
150  }
151 
152  if (!member__f_)
153  return optional_info;
154 
155  lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0);
156 
157  optional_info.member__f_pointer_value = member__f_pointer_value;
158 
159  if (!member__f_pointer_value)
160  return optional_info;
161 
162  ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
163  Process *process = exe_ctx.GetProcessPtr();
164 
165  if (process == nullptr)
166  return optional_info;
167 
168  uint32_t address_size = process->GetAddressByteSize();
169  Status status;
170 
171  // First item pointed to by __f_ should be the pointer to the vtable for
172  // a __base object.
173  lldb::addr_t vtable_address =
174  process->ReadPointerFromMemory(member__f_pointer_value, status);
175 
176  if (status.Fail())
177  return optional_info;
178 
179  lldb::addr_t vtable_address_first_entry =
180  process->ReadPointerFromMemory(vtable_address + address_size, status);
181 
182  if (status.Fail())
183  return optional_info;
184 
185  lldb::addr_t address_after_vtable = member__f_pointer_value + address_size;
186  // As commented above we may not have a function pointer but if we do we will
187  // need it.
188  lldb::addr_t possible_function_address =
189  process->ReadPointerFromMemory(address_after_vtable, status);
190 
191  if (status.Fail())
192  return optional_info;
193 
194  Target &target = process->GetTarget();
195 
196  if (target.GetSectionLoadList().IsEmpty())
197  return optional_info;
198 
199  Address vtable_first_entry_resolved;
200 
202  vtable_address_first_entry, vtable_first_entry_resolved))
203  return optional_info;
204 
205  Address vtable_addr_resolved;
206  SymbolContext sc;
207  Symbol *symbol = nullptr;
208 
209  if (!target.GetSectionLoadList().ResolveLoadAddress(vtable_address,
210  vtable_addr_resolved))
211  return optional_info;
212 
214  vtable_addr_resolved, eSymbolContextEverything, sc);
215  symbol = sc.symbol;
216 
217  if (symbol == nullptr)
218  return optional_info;
219 
220  llvm::StringRef vtable_name(symbol->GetName().GetStringRef());
221  bool found_expected_start_string =
222  vtable_name.startswith("vtable for std::__1::__function::__func<");
223 
224  if (!found_expected_start_string)
225  return optional_info;
226 
227  // Given case 1 or 3 we have a vtable name, we are want to extract the first
228  // template parameter
229  //
230  // ... __func<main::$_0, std::__1::allocator<main::$_0> ...
231  // ^^^^^^^^^
232  //
233  // We could see names such as:
234  // main::$_0
235  // Bar::add_num2(int)::'lambda'(int)
236  // Bar
237  //
238  // We do this by find the first < and , and extracting in between.
239  //
240  // This covers the case of the lambda known at compile time.
241  size_t first_open_angle_bracket = vtable_name.find('<') + 1;
242  size_t first_comma = vtable_name.find(',');
243 
244  llvm::StringRef first_template_parameter =
245  vtable_name.slice(first_open_angle_bracket, first_comma);
246 
247  Address function_address_resolved;
248 
249  // Setup for cases 2, 4 and 5 we have a pointer to a function after the
250  // vtable. We will use a process of elimination to drop through each case
251  // and obtain the data we need.
253  possible_function_address, function_address_resolved)) {
255  function_address_resolved, eSymbolContextEverything, sc);
256  symbol = sc.symbol;
257  }
258 
259  // These conditions are used several times to simplify statements later on.
260  bool has___invoke =
261  (symbol ? symbol->GetName().GetStringRef().contains("__invoke") : false);
262  auto calculate_symbol_context_helper = [](auto &t,
263  SymbolContextList &sc_list) {
264  SymbolContext sc;
265  t->CalculateSymbolContext(&sc);
266  sc_list.Append(sc);
267  };
268 
269  // Case 2
270  if (has___invoke) {
271  SymbolContextList scl;
272  calculate_symbol_context_helper(symbol, scl);
273 
274  return line_entry_helper(target, scl[0], symbol, first_template_parameter,
275  has___invoke);
276  }
277 
278  // Case 4 or 5
279  if (symbol && !symbol->GetName().GetStringRef().startswith("vtable for") &&
280  !contains_lambda_identifier(first_template_parameter) && !has___invoke) {
281  optional_info.callable_case =
283  optional_info.callable_address = function_address_resolved;
284  optional_info.callable_symbol = *symbol;
285 
286  return optional_info;
287  }
288 
289  std::string func_to_match = first_template_parameter.str();
290 
291  auto it = CallableLookupCache.find(func_to_match);
292  if (it != CallableLookupCache.end())
293  return it->second;
294 
295  SymbolContextList scl;
296 
297  CompileUnit *vtable_cu =
298  vtable_first_entry_resolved.CalculateSymbolContextCompileUnit();
299  llvm::StringRef name_to_use = func_to_match;
300 
301  // Case 3, we have a callable object instead of a lambda
302  //
303  // TODO
304  // We currently don't support this case a callable object may have multiple
305  // operator()() varying on const/non-const and number of arguments and we
306  // don't have a way to currently distinguish them so we will bail out now.
307  if (!contains_lambda_identifier(name_to_use))
308  return optional_info;
309 
310  if (vtable_cu && !has___invoke) {
311  lldb::FunctionSP func_sp =
312  vtable_cu->FindFunction([name_to_use](const FunctionSP &f) {
313  auto name = f->GetName().GetStringRef();
314  if (name.startswith(name_to_use) && name.contains("operator"))
315  return true;
316 
317  return false;
318  });
319 
320  if (func_sp) {
321  calculate_symbol_context_helper(func_sp, scl);
322  }
323  }
324 
325  if (symbol == nullptr)
326  return optional_info;
327 
328  // Case 1 or 3
329  if (scl.GetSize() >= 1) {
330  optional_info = line_entry_helper(target, scl[0], symbol,
331  first_template_parameter, has___invoke);
332  }
333 
334  CallableLookupCache[func_to_match] = optional_info;
335 
336  return optional_info;
337 }
338 
339 lldb::ThreadPlanSP
341  bool stop_others) {
342  ThreadPlanSP ret_plan_sp;
343 
344  lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
345 
346  TargetSP target_sp(thread.CalculateTarget());
347 
348  if (target_sp->GetSectionLoadList().IsEmpty())
349  return ret_plan_sp;
350 
351  Address pc_addr_resolved;
352  SymbolContext sc;
353  Symbol *symbol;
354 
355  if (!target_sp->GetSectionLoadList().ResolveLoadAddress(curr_pc,
356  pc_addr_resolved))
357  return ret_plan_sp;
358 
359  target_sp->GetImages().ResolveSymbolContextForAddress(
360  pc_addr_resolved, eSymbolContextEverything, sc);
361  symbol = sc.symbol;
362 
363  if (symbol == nullptr)
364  return ret_plan_sp;
365 
366  llvm::StringRef function_name(symbol->GetName().GetCString());
367 
368  // Handling the case where we are attempting to step into std::function.
369  // The behavior will be that we will attempt to obtain the wrapped
370  // callable via FindLibCppStdFunctionCallableInfo() and if we find it we
371  // will return a ThreadPlanRunToAddress to the callable. Therefore we will
372  // step into the wrapped callable.
373  //
374  bool found_expected_start_string =
375  function_name.startswith("std::__1::function<");
376 
377  if (!found_expected_start_string)
378  return ret_plan_sp;
379 
380  AddressRange range_of_curr_func;
381  sc.GetAddressRange(eSymbolContextEverything, 0, false, range_of_curr_func);
382 
383  StackFrameSP frame = thread.GetStackFrameAtIndex(0);
384 
385  if (frame) {
386  ValueObjectSP value_sp = frame->FindVariable(g_this);
387 
390 
392  value_sp->GetValueIsValid()) {
393  // We found the std::function wrapped callable and we have its address.
394  // We now create a ThreadPlan to run to the callable.
395  ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
396  thread, callable_info.callable_address, stop_others);
397  return ret_plan_sp;
398  } else {
399  // We are in std::function but we could not obtain the callable.
400  // We create a ThreadPlan to keep stepping through using the address range
401  // of the current function.
402  ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
403  thread, range_of_curr_func, sc, nullptr, eOnlyThisThread,
405  return ret_plan_sp;
406  }
407  }
408 
409  return ret_plan_sp;
410 }
lldb_private::AddressRange::GetBaseAddress
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
Block.h
lldb_private::Address::CalculateSymbolContextCompileUnit
CompileUnit * CalculateSymbolContextCompileUnit() const
Definition: Address.cpp:834
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableInfo::callable_symbol
Symbol callable_symbol
Definition: CPPLanguageRuntime.h:32
CompileUnit.h
lldb_private::CompileUnit::FindFunction
lldb::FunctionSP FindFunction(llvm::function_ref< bool(const lldb::FunctionSP &)> matching_lambda)
Find a function in the compile unit based on the predicate matching_lambda.
Definition: CompileUnit.cpp:76
lldb_private::Value
Definition: Value.h:38
lldb_private::Symbol
Definition: Symbol.h:20
lldb_private::ExecutionContext::GetProcessPtr
Process * GetProcessPtr() const
Returns a pointer to the process object.
Definition: ExecutionContext.cpp:208
lldb_private::SymbolContext::GetAddressRange
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
Definition: SymbolContext.cpp:379
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
lldb_private::Process
Definition: Process.h:340
lldb_private::Thread::CalculateTarget
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1389
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1208
lldb_private::SymbolContextList
Definition: SymbolContext.h:379
SectionLoadList.h
StackFrame.h
lldb_private::Stream
Definition: Stream.h:28
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::CPPLanguageRuntime::IsAllowedRuntimeValue
bool IsAllowedRuntimeValue(ConstString name) override
Identify whether a name is a runtime value that should not be hidden by from the user interface.
Definition: CPPLanguageRuntime.cpp:43
UniqueCStringMap.h
lldb_private::Target::ResolveLoadAddress
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow)
Definition: Target.cpp:2818
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:450
ABI.h
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:924
lldb_private::CompileUnit
Definition: CompileUnit.h:38
lldb_private::Address::CalculateSymbolContextLineEntry
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const
Definition: Address.cpp:890
lldb_private::SymbolContext::symbol
Symbol * symbol
The Symbol for a given query.
Definition: SymbolContext.h:323
ID
static char ID
Definition: IRDynamicChecks.cpp:32
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject
@ CallableObject
lldb_private::ExecutionContextScope
Definition: ExecutionContextScope.h:32
lldb_private::Thread
Definition: Thread.h:60
lldb_private::Address::GetCallableLoadAddress
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition: Address.cpp:335
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction
@ FreeOrMemberFunction
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
lldb_private::Process::GetAddressByteSize
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3336
lldb_private::SymbolContextList::GetSize
uint32_t GetSize() const
Get accessor for a symbol context list size.
Definition: SymbolContext.cpp:1278
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::AddressRange
Definition: AddressRange.h:25
Timer.h
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid
@ Invalid
LLDB_SCOPED_TIMER
#define LLDB_SCOPED_TIMER()
Definition: Timer.h:83
lldb_private::LanguageRuntime
Definition: LanguageRuntime.h:60
ThreadPlanRunToAddress.h
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo
LibCppStdFunctionCallableInfo FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp)
Definition: CPPLanguageRuntime.cpp:100
CPPLanguageRuntime.h
lldb_private::CPPLanguageRuntime::GetStepThroughTrampolinePlan
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override
Obtain a ThreadPlan to get us into C++ constructs such as std::function.
Definition: CPPLanguageRuntime.cpp:340
lldb_private::ModuleList::ResolveSymbolContextForAddress
uint32_t ResolveSymbolContextForAddress(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) const
Resolve the symbol context for the given address. (const Address
Definition: ModuleList.cpp:641
lldb_private::SectionLoadList::ResolveLoadAddress
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, bool allow_section_end=false) const
Definition: SectionLoadList.cpp:208
VariableList.h
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableInfo::member__f_pointer_value
lldb::addr_t member__f_pointer_value
Definition: CPPLanguageRuntime.h:35
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableInfo::callable_case
LibCppStdFunctionCallableCase callable_case
Definition: CPPLanguageRuntime.h:36
lldb_private::Symbol::GetName
ConstString GetName() const
Definition: Symbol.cpp:500
lldb_private::SectionLoadList::IsEmpty
bool IsEmpty() const
Definition: SectionLoadList.cpp:37
ThreadPlanStepInRange.h
lldb_private::Status
Definition: Status.h:44
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
uint32_t
lldb_private::CPPLanguageRuntime::CallableLookupCache
OperatorStringToCallableInfoMap CallableLookupCache
Definition: CPPLanguageRuntime.h:89
lldb_private::Address
Definition: Address.h:59
contains_lambda_identifier
bool contains_lambda_identifier(llvm::StringRef &str_ref)
Definition: CPPLanguageRuntime.cpp:59
PluginManager.h
lldb_private::Target::GetSectionLoadList
SectionLoadList & GetSectionLoadList()
Definition: Target.h:1039
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::CPPLanguageRuntime::GetObjectDescription
bool GetObjectDescription(Stream &str, ValueObject &object) override
Definition: CPPLanguageRuntime.cpp:47
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableInfo
Definition: CPPLanguageRuntime.h:31
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableInfo::callable_address
Address callable_address
Definition: CPPLanguageRuntime.h:33
lldb_private::Process::ReadPointerFromMemory
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2122
lldb_private::Thread::GetStackFrameAtIndex
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:397
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableInfo::callable_line_entry
LineEntry callable_line_entry
Definition: CPPLanguageRuntime.h:34
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
Variable.h
line_entry_helper
CPPLanguageRuntime::LibCppStdFunctionCallableInfo line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol, llvm::StringRef first_template_param_sref, bool has___invoke)
Definition: CPPLanguageRuntime.cpp:64
g_this
static ConstString g_this
Definition: CPPLanguageRuntime.cpp:36
lldb
Definition: SBAddress.h:15
RegisterContext.h
lldb_private::LineEntry
Definition: LineEntry.h:20
ExecutionContext.h
lldb::eOnlyThisThread
@ eOnlyThisThread
Definition: lldb-enumerations.h:135
lldb_private::CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda
@ Lambda