1 //===-- CPPLanguageRuntime.cpp---------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
14 #include "CPPLanguageRuntime.h"
16 #include "llvm/ADT/StringRef.h"
18 #include "lldb/Symbol/Block.h"
19 #include "lldb/Symbol/Variable.h"
20 #include "lldb/Symbol/VariableList.h"
22 #include "lldb/Core/PluginManager.h"
23 #include "lldb/Core/UniqueCStringMap.h"
24 #include "lldb/Symbol/CompileUnit.h"
25 #include "lldb/Target/ABI.h"
26 #include "lldb/Target/ExecutionContext.h"
27 #include "lldb/Target/RegisterContext.h"
28 #include "lldb/Target/SectionLoadList.h"
29 #include "lldb/Target/StackFrame.h"
30 #include "lldb/Target/StackFrameRecognizer.h"
31 #include "lldb/Target/ThreadPlanRunToAddress.h"
32 #include "lldb/Target/ThreadPlanStepInRange.h"
33 #include "lldb/Utility/Timer.h"
36 using namespace lldb_private
;
38 static ConstString g_this
= ConstString("this");
39 // Artificial coroutine-related variables emitted by clang.
40 static ConstString g_promise
= ConstString("__promise");
41 static ConstString g_coro_frame
= ConstString("__coro_frame");
43 char CPPLanguageRuntime::ID
= 0;
45 /// A frame recognizer that is installed to hide libc++ implementation
46 /// details from the backtrace.
47 class LibCXXFrameRecognizer
: public StackFrameRecognizer
{
48 std::array
<RegularExpression
, 2> m_hidden_regex
;
49 RecognizedStackFrameSP m_hidden_frame
;
51 struct LibCXXHiddenFrame
: public RecognizedStackFrame
{
52 bool ShouldHide() override
{ return true; }
56 LibCXXFrameRecognizer()
58 // internal implementation details in the `std::` namespace
59 // std::__1::__function::__alloc_func<void (*)(), std::__1::allocator<void (*)()>, void ()>::operator()[abi:ne200000]
60 // std::__1::__function::__func<void (*)(), std::__1::allocator<void (*)()>, void ()>::operator()
61 // std::__1::__function::__value_func<void ()>::operator()[abi:ne200000]() const
62 // std::__2::__function::__policy_invoker<void (int, int)>::__call_impl[abi:ne200000]<std::__2::__function::__default_alloc_func<int (*)(int, int), int (int, int)>>
63 // std::__1::__invoke[abi:ne200000]<void (*&)()>
64 // std::__1::__invoke_void_return_wrapper<void, true>::__call[abi:ne200000]<void (*&)()>
65 RegularExpression
{R
"(^std::__[^:]*::__)"},
66 // internal implementation details in the `std::ranges` namespace
67 // std::__1::ranges::__sort::__sort_fn_impl[abi:ne200000]<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, bool (*)(int, int), std::__1::identity>
68 RegularExpression
{R
"(^std::__[^:]*::ranges::__)"},
70 m_hidden_frame(new LibCXXHiddenFrame()) {}
72 std::string
GetName() override
{ return "libc++ frame recognizer"; }
74 lldb::RecognizedStackFrameSP
75 RecognizeFrame(lldb::StackFrameSP frame_sp
) override
{
78 const auto &sc
= frame_sp
->GetSymbolContext(lldb::eSymbolContextFunction
);
82 // Check if we have a regex match
83 for (RegularExpression
&r
: m_hidden_regex
) {
84 if (!r
.Execute(sc
.function
->GetNameNoArguments()))
87 // Only hide this frame if the immediate caller is also within libc++.
88 lldb::ThreadSP thread_sp
= frame_sp
->GetThread();
91 lldb::StackFrameSP parent_frame_sp
=
92 thread_sp
->GetStackFrameAtIndex(frame_sp
->GetFrameIndex() + 1);
95 const auto &parent_sc
=
96 parent_frame_sp
->GetSymbolContext(lldb::eSymbolContextFunction
);
97 if (!parent_sc
.function
)
99 if (parent_sc
.function
->GetNameNoArguments().GetStringRef().starts_with(
101 return m_hidden_frame
;
108 CPPLanguageRuntime::CPPLanguageRuntime(Process
*process
)
109 : LanguageRuntime(process
) {
111 process
->GetTarget().GetFrameRecognizerManager().AddRecognizer(
112 StackFrameRecognizerSP(new LibCXXFrameRecognizer()), {},
113 std::make_shared
<RegularExpression
>("^std::__[^:]*::"),
114 /*mangling_preference=*/Mangled::ePreferDemangledWithoutArguments
,
115 /*first_instruction_only=*/false);
118 bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name
) {
119 return name
== g_this
|| name
== g_promise
|| name
== g_coro_frame
;
122 llvm::Error
CPPLanguageRuntime::GetObjectDescription(Stream
&str
,
123 ValueObject
&object
) {
124 // C++ has no generic way to do this.
125 return llvm::createStringError("C++ does not support object descriptions");
129 CPPLanguageRuntime::GetObjectDescription(Stream
&str
, Value
&value
,
130 ExecutionContextScope
*exe_scope
) {
131 // C++ has no generic way to do this.
132 return llvm::createStringError("C++ does not support object descriptions");
135 bool contains_lambda_identifier(llvm::StringRef
&str_ref
) {
136 return str_ref
.contains("$_") || str_ref
.contains("'lambda'");
139 CPPLanguageRuntime::LibCppStdFunctionCallableInfo
140 line_entry_helper(Target
&target
, const SymbolContext
&sc
, Symbol
*symbol
,
141 llvm::StringRef first_template_param_sref
, bool has_invoke
) {
143 CPPLanguageRuntime::LibCppStdFunctionCallableInfo optional_info
;
146 sc
.GetAddressRange(eSymbolContextEverything
, 0, false, range
);
148 Address address
= range
.GetBaseAddress();
151 if (target
.ResolveLoadAddress(address
.GetCallableLoadAddress(&target
),
153 LineEntry line_entry
;
154 addr
.CalculateSymbolContextLineEntry(line_entry
);
156 if (contains_lambda_identifier(first_template_param_sref
) || has_invoke
) {
158 optional_info
.callable_case
= lldb_private::CPPLanguageRuntime::
159 LibCppStdFunctionCallableCase::Lambda
;
162 optional_info
.callable_case
= lldb_private::CPPLanguageRuntime::
163 LibCppStdFunctionCallableCase::CallableObject
;
166 optional_info
.callable_symbol
= *symbol
;
167 optional_info
.callable_line_entry
= line_entry
;
168 optional_info
.callable_address
= addr
;
171 return optional_info
;
174 CPPLanguageRuntime::LibCppStdFunctionCallableInfo
175 CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
176 lldb::ValueObjectSP
&valobj_sp
) {
179 LibCppStdFunctionCallableInfo optional_info
;
182 return optional_info
;
184 // Member __f_ has type __base*, the contents of which will hold:
185 // 1) a vtable entry which may hold type information needed to discover the
186 // lambda being called
187 // 2) possibly hold a pointer to the callable object
190 // (lldb) frame var -R f_display
191 // (std::__1::function<void (int)>) f_display = {
195 // __f_ = 0x00007ffeefbffa00
197 // (lldb) memory read -fA 0x00007ffeefbffa00
198 // 0x7ffeefbffa00: ... `vtable for std::__1::__function::__func<void (*) ...
199 // 0x7ffeefbffa08: ... `print_num(int) at std_function_cppreference_exam ...
201 // We will be handling five cases below, std::function is wrapping:
203 // 1) a lambda we know at compile time. We will obtain the name of the lambda
204 // from the first template pameter from __func's vtable. We will look up
205 // the lambda's operator()() and obtain the line table entry.
206 // 2) a lambda we know at runtime. A pointer to the lambdas __invoke method
207 // will be stored after the vtable. We will obtain the lambdas name from
208 // this entry and lookup operator()() and obtain the line table entry.
209 // 3) a callable object via operator()(). We will obtain the name of the
210 // object from the first template parameter from __func's vtable. We will
211 // look up the objects operator()() and obtain the line table entry.
212 // 4) a member function. A pointer to the function will stored after the
213 // we will obtain the name from this pointer.
214 // 5) a free function. A pointer to the function will stored after the vtable
215 // we will obtain the name from this pointer.
216 ValueObjectSP
member_f_(valobj_sp
->GetChildMemberWithName("__f_"));
219 ValueObjectSP
sub_member_f_(member_f_
->GetChildMemberWithName("__f_"));
222 member_f_
= sub_member_f_
;
226 return optional_info
;
228 lldb::addr_t member_f_pointer_value
= member_f_
->GetValueAsUnsigned(0);
230 optional_info
.member_f_pointer_value
= member_f_pointer_value
;
232 if (!member_f_pointer_value
)
233 return optional_info
;
235 ExecutionContext
exe_ctx(valobj_sp
->GetExecutionContextRef());
236 Process
*process
= exe_ctx
.GetProcessPtr();
238 if (process
== nullptr)
239 return optional_info
;
241 uint32_t address_size
= process
->GetAddressByteSize();
244 // First item pointed to by __f_ should be the pointer to the vtable for
246 lldb::addr_t vtable_address
=
247 process
->ReadPointerFromMemory(member_f_pointer_value
, status
);
250 return optional_info
;
252 lldb::addr_t vtable_address_first_entry
=
253 process
->ReadPointerFromMemory(vtable_address
+ address_size
, status
);
256 return optional_info
;
258 lldb::addr_t address_after_vtable
= member_f_pointer_value
+ address_size
;
259 // As commented above we may not have a function pointer but if we do we will
261 lldb::addr_t possible_function_address
=
262 process
->ReadPointerFromMemory(address_after_vtable
, status
);
265 return optional_info
;
267 Target
&target
= process
->GetTarget();
269 if (target
.GetSectionLoadList().IsEmpty())
270 return optional_info
;
272 Address vtable_first_entry_resolved
;
274 if (!target
.GetSectionLoadList().ResolveLoadAddress(
275 vtable_address_first_entry
, vtable_first_entry_resolved
))
276 return optional_info
;
278 Address vtable_addr_resolved
;
280 Symbol
*symbol
= nullptr;
282 if (!target
.GetSectionLoadList().ResolveLoadAddress(vtable_address
,
283 vtable_addr_resolved
))
284 return optional_info
;
286 target
.GetImages().ResolveSymbolContextForAddress(
287 vtable_addr_resolved
, eSymbolContextEverything
, sc
);
290 if (symbol
== nullptr)
291 return optional_info
;
293 llvm::StringRef
vtable_name(symbol
->GetName().GetStringRef());
294 bool found_expected_start_string
=
295 vtable_name
.starts_with("vtable for std::__1::__function::__func<");
297 if (!found_expected_start_string
)
298 return optional_info
;
300 // Given case 1 or 3 we have a vtable name, we are want to extract the first
301 // template parameter
303 // ... __func<main::$_0, std::__1::allocator<main::$_0> ...
306 // We could see names such as:
308 // Bar::add_num2(int)::'lambda'(int)
311 // We do this by find the first < and , and extracting in between.
313 // This covers the case of the lambda known at compile time.
314 size_t first_open_angle_bracket
= vtable_name
.find('<') + 1;
315 size_t first_comma
= vtable_name
.find(',');
317 llvm::StringRef first_template_parameter
=
318 vtable_name
.slice(first_open_angle_bracket
, first_comma
);
320 Address function_address_resolved
;
322 // Setup for cases 2, 4 and 5 we have a pointer to a function after the
323 // vtable. We will use a process of elimination to drop through each case
324 // and obtain the data we need.
325 if (target
.GetSectionLoadList().ResolveLoadAddress(
326 possible_function_address
, function_address_resolved
)) {
327 target
.GetImages().ResolveSymbolContextForAddress(
328 function_address_resolved
, eSymbolContextEverything
, sc
);
332 // These conditions are used several times to simplify statements later on.
334 (symbol
? symbol
->GetName().GetStringRef().contains("__invoke") : false);
335 auto calculate_symbol_context_helper
= [](auto &t
,
336 SymbolContextList
&sc_list
) {
338 t
->CalculateSymbolContext(&sc
);
344 SymbolContextList scl
;
345 calculate_symbol_context_helper(symbol
, scl
);
347 return line_entry_helper(target
, scl
[0], symbol
, first_template_parameter
,
352 if (symbol
&& !symbol
->GetName().GetStringRef().starts_with("vtable for") &&
353 !contains_lambda_identifier(first_template_parameter
) && !has_invoke
) {
354 optional_info
.callable_case
=
355 LibCppStdFunctionCallableCase::FreeOrMemberFunction
;
356 optional_info
.callable_address
= function_address_resolved
;
357 optional_info
.callable_symbol
= *symbol
;
359 return optional_info
;
362 std::string func_to_match
= first_template_parameter
.str();
364 auto it
= CallableLookupCache
.find(func_to_match
);
365 if (it
!= CallableLookupCache
.end())
368 SymbolContextList scl
;
370 CompileUnit
*vtable_cu
=
371 vtable_first_entry_resolved
.CalculateSymbolContextCompileUnit();
372 llvm::StringRef name_to_use
= func_to_match
;
374 // Case 3, we have a callable object instead of a lambda
377 // We currently don't support this case a callable object may have multiple
378 // operator()() varying on const/non-const and number of arguments and we
379 // don't have a way to currently distinguish them so we will bail out now.
380 if (!contains_lambda_identifier(name_to_use
))
381 return optional_info
;
383 if (vtable_cu
&& !has_invoke
) {
384 lldb::FunctionSP func_sp
=
385 vtable_cu
->FindFunction([name_to_use
](const FunctionSP
&f
) {
386 auto name
= f
->GetName().GetStringRef();
387 if (name
.starts_with(name_to_use
) && name
.contains("operator"))
394 calculate_symbol_context_helper(func_sp
, scl
);
398 if (symbol
== nullptr)
399 return optional_info
;
402 if (scl
.GetSize() >= 1) {
403 optional_info
= line_entry_helper(target
, scl
[0], symbol
,
404 first_template_parameter
, has_invoke
);
407 CallableLookupCache
[func_to_match
] = optional_info
;
409 return optional_info
;
413 CPPLanguageRuntime::GetStepThroughTrampolinePlan(Thread
&thread
,
415 ThreadPlanSP ret_plan_sp
;
417 lldb::addr_t curr_pc
= thread
.GetRegisterContext()->GetPC();
419 TargetSP
target_sp(thread
.CalculateTarget());
421 if (target_sp
->GetSectionLoadList().IsEmpty())
424 Address pc_addr_resolved
;
428 if (!target_sp
->GetSectionLoadList().ResolveLoadAddress(curr_pc
,
432 target_sp
->GetImages().ResolveSymbolContextForAddress(
433 pc_addr_resolved
, eSymbolContextEverything
, sc
);
436 if (symbol
== nullptr)
439 llvm::StringRef
function_name(symbol
->GetName().GetCString());
441 // Handling the case where we are attempting to step into std::function.
442 // The behavior will be that we will attempt to obtain the wrapped
443 // callable via FindLibCppStdFunctionCallableInfo() and if we find it we
444 // will return a ThreadPlanRunToAddress to the callable. Therefore we will
445 // step into the wrapped callable.
447 bool found_expected_start_string
=
448 function_name
.starts_with("std::__1::function<");
450 if (!found_expected_start_string
)
453 AddressRange range_of_curr_func
;
454 sc
.GetAddressRange(eSymbolContextEverything
, 0, false, range_of_curr_func
);
456 StackFrameSP frame
= thread
.GetStackFrameAtIndex(0);
459 ValueObjectSP value_sp
= frame
->FindVariable(g_this
);
461 CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info
=
462 FindLibCppStdFunctionCallableInfo(value_sp
);
464 if (callable_info
.callable_case
!= LibCppStdFunctionCallableCase::Invalid
&&
465 value_sp
->GetValueIsValid()) {
466 // We found the std::function wrapped callable and we have its address.
467 // We now create a ThreadPlan to run to the callable.
468 ret_plan_sp
= std::make_shared
<ThreadPlanRunToAddress
>(
469 thread
, callable_info
.callable_address
, stop_others
);
472 // We are in std::function but we could not obtain the callable.
473 // We create a ThreadPlan to keep stepping through using the address range
474 // of the current function.
475 ret_plan_sp
= std::make_shared
<ThreadPlanStepInRange
>(
476 thread
, range_of_curr_func
, sc
, nullptr, eOnlyThisThread
,
477 eLazyBoolYes
, eLazyBoolYes
);