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#include <iostream>
11
12#include <memory>
13
14#include "CPPLanguageRuntime.h"
16#include "ItaniumABIRuntime.h"
17#include "MicrosoftABIRuntime.h"
19
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/Error.h"
22
23#include "lldb/Symbol/Block.h"
26
30#include "lldb/Target/ABI.h"
39#include "lldb/Utility/Timer.h"
40
41using namespace lldb;
42using namespace lldb_private;
43
45
47// Artificial coroutine-related variables emitted by clang.
48static ConstString g_promise = ConstString("__promise");
49static ConstString g_coro_frame = ConstString("__coro_frame");
50
51char CPPLanguageRuntime::ID = 0;
52
53/// A frame recognizer that is installed to hide libc++ implementation
54/// details from the backtrace.
56 std::array<RegularExpression, 2> m_hidden_regex;
58
60 bool ShouldHide() override { return true; }
61 };
62
63public:
66 // internal implementation details in the `std::` namespace
67 // std::__1::__function::__alloc_func<void (*)(), std::__1::allocator<void (*)()>, void ()>::operator()[abi:ne200000]
68 // std::__1::__function::__func<void (*)(), std::__1::allocator<void (*)()>, void ()>::operator()
69 // std::__1::__function::__value_func<void ()>::operator()[abi:ne200000]() const
70 // std::__2::__function::__policy_invoker<void (int, int)>::__call_impl[abi:ne200000]<std::__2::__function::__default_alloc_func<int (*)(int, int), int (int, int)>>
71 // std::__1::__invoke[abi:ne200000]<void (*&)()>
72 // std::__1::__invoke_void_return_wrapper<void, true>::__call[abi:ne200000]<void (*&)()>
73 RegularExpression{R"(^std::__[^:]*::__)"},
74 // internal implementation details in the `std::ranges` namespace
75 // 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>
76 RegularExpression{R"(^std::__[^:]*::ranges::__)"},
77 },
79
80 std::string GetName() override { return "libc++ frame recognizer"; }
81
84 if (!frame_sp)
85 return {};
86 const auto &sc = frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
87 if (!sc.function)
88 return {};
89
90 // Check if we have a regex match
92 if (!r.Execute(sc.function->GetNameNoArguments()))
93 continue;
94
95 // Only hide this frame if the immediate caller is also within libc++.
96 lldb::ThreadSP thread_sp = frame_sp->GetThread();
97 if (!thread_sp)
98 return {};
99 lldb::StackFrameSP parent_frame_sp =
100 thread_sp->GetStackFrameAtIndex(frame_sp->GetFrameIndex() + 1);
101 if (!parent_frame_sp)
102 return {};
103 const auto &parent_sc =
104 parent_frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
105 if (!parent_sc.function)
106 return {};
107 if (parent_sc.function->GetNameNoArguments().GetStringRef().starts_with(
108 "std::"))
109 return m_hidden_frame;
110 }
111
112 return {};
113 }
114};
115
117 : LanguageRuntime(process) {
118 if (process) {
121 std::make_shared<RegularExpression>("^std::__[^:]*::"),
122 /*mangling_preference=*/Mangled::ePreferDemangledWithoutArguments,
123 /*first_instruction_only=*/false);
124
126 }
127
128 m_abi_runtimes.emplace_back(new ItaniumABIRuntime(process));
129 if (process->GetTarget().GetArchitecture().GetTriple().isOSWindows())
130 m_abi_runtimes.emplace_back(new MicrosoftABIRuntime(process));
131}
132
134 return name == g_this || name == g_promise || name == g_coro_frame;
135}
136
138 ValueObject &object) {
139 // C++ has no generic way to do this.
140 return llvm::createStringError("C++ does not support object descriptions");
141}
142
143llvm::Error
145 ExecutionContextScope *exe_scope) {
146 // C++ has no generic way to do this.
147 return llvm::createStringError("C++ does not support object descriptions");
148}
149
150bool contains_lambda_identifier(llvm::StringRef &str_ref) {
151 return str_ref.contains("$_") || str_ref.contains("'lambda'");
152}
153
155line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol,
156 llvm::StringRef first_template_param_sref, bool has_invoke) {
157
159
160 Address address = sc.GetFunctionOrSymbolAddress();
161
162 Address addr;
163 if (target.ResolveLoadAddress(address.GetCallableLoadAddress(&target),
164 addr)) {
165 LineEntry line_entry;
166 addr.CalculateSymbolContextLineEntry(line_entry);
167
168 if (contains_lambda_identifier(first_template_param_sref) || has_invoke) {
169 // Case 1 and 2
170 optional_info.callable_case = lldb_private::CPPLanguageRuntime::
171 LibCppStdFunctionCallableCase::Lambda;
172 } else {
173 // Case 3
174 optional_info.callable_case = lldb_private::CPPLanguageRuntime::
175 LibCppStdFunctionCallableCase::CallableObject;
176 }
177
178 optional_info.callable_symbol = *symbol;
179 optional_info.callable_line_entry = line_entry;
180 optional_info.callable_address = addr;
181 }
182
183 return optional_info;
184}
185
188 lldb::ValueObjectSP &valobj_sp) {
190
191 LibCppStdFunctionCallableInfo optional_info;
192
193 if (!valobj_sp)
194 return optional_info;
195
196 // Member __f_ has type __base*, the contents of which will hold:
197 // 1) a vtable entry which may hold type information needed to discover the
198 // lambda being called
199 // 2) possibly hold a pointer to the callable object
200 // e.g.
201 //
202 // (lldb) frame var -R f_display
203 // (std::__1::function<void (int)>) f_display = {
204 // __buf_ = {
205 // …
206 // }
207 // __f_ = 0x00007ffeefbffa00
208 // }
209 // (lldb) memory read -fA 0x00007ffeefbffa00
210 // 0x7ffeefbffa00: ... `vtable for std::__1::__function::__func<void (*) ...
211 // 0x7ffeefbffa08: ... `print_num(int) at std_function_cppreference_exam ...
212 //
213 // We will be handling five cases below, std::function is wrapping:
214 //
215 // 1) a lambda we know at compile time. We will obtain the name of the lambda
216 // from the first template pameter from __func's vtable. We will look up
217 // the lambda's operator()() and obtain the line table entry.
218 // 2) a lambda we know at runtime. A pointer to the lambdas __invoke method
219 // will be stored after the vtable. We will obtain the lambdas name from
220 // this entry and lookup operator()() and obtain the line table entry.
221 // 3) a callable object via operator()(). We will obtain the name of the
222 // object from the first template parameter from __func's vtable. We will
223 // look up the objects operator()() and obtain the line table entry.
224 // 4) a member function. A pointer to the function will stored after the
225 // we will obtain the name from this pointer.
226 // 5) a free function. A pointer to the function will stored after the vtable
227 // we will obtain the name from this pointer.
228 ValueObjectSP member_f_(valobj_sp->GetChildMemberWithName("__f_"));
229
230 if (member_f_) {
231 ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName("__f_"));
232
233 if (sub_member_f_)
234 member_f_ = sub_member_f_;
235 }
236
237 if (!member_f_)
238 return optional_info;
239
240 lldb::addr_t member_f_pointer_value = member_f_->GetValueAsUnsigned(0);
241
242 optional_info.member_f_pointer_value = member_f_pointer_value;
243
244 if (!member_f_pointer_value)
245 return optional_info;
246
247 ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
248 Process *process = exe_ctx.GetProcessPtr();
249
250 if (process == nullptr)
251 return optional_info;
252
253 uint32_t address_size = process->GetAddressByteSize();
254
255 // First item pointed to by __f_ should be the pointer to the vtable for
256 // a __base object.
257 llvm::Expected<lldb::addr_t> vtable_address_or_err =
258 process->ReadPointerFromMemory(member_f_pointer_value);
259 if (!vtable_address_or_err) {
260 llvm::consumeError(vtable_address_or_err.takeError());
261 return optional_info;
262 }
263 lldb::addr_t vtable_address = *vtable_address_or_err;
264
265 ABISP abi_sp = process->GetABI();
266 if (abi_sp)
267 vtable_address = abi_sp->FixCodeAddress(vtable_address);
268
269 llvm::Expected<lldb::addr_t> vtable_address_first_entry_or_err =
270 process->ReadPointerFromMemory(vtable_address + address_size);
271 if (!vtable_address_first_entry_or_err) {
272 llvm::consumeError(vtable_address_first_entry_or_err.takeError());
273 return optional_info;
274 }
275 lldb::addr_t vtable_address_first_entry = *vtable_address_first_entry_or_err;
276
277 if (abi_sp)
278 vtable_address_first_entry =
279 abi_sp->FixCodeAddress(vtable_address_first_entry);
280
281 lldb::addr_t address_after_vtable = member_f_pointer_value + address_size;
282 // As commented above we may not have a function pointer but if we do we will
283 // need it.
284 llvm::Expected<lldb::addr_t> possible_function_address_or_err =
285 process->ReadPointerFromMemory(address_after_vtable);
286 if (!possible_function_address_or_err) {
287 llvm::consumeError(possible_function_address_or_err.takeError());
288 return optional_info;
289 }
290 lldb::addr_t possible_function_address = *possible_function_address_or_err;
291
292 if (abi_sp)
293 possible_function_address =
294 abi_sp->FixCodeAddress(possible_function_address);
295
296 Target &target = process->GetTarget();
297
298 if (!target.HasLoadedSections())
299 return optional_info;
300
301 Address vtable_first_entry_resolved;
302
303 if (!target.ResolveLoadAddress(vtable_address_first_entry,
304 vtable_first_entry_resolved))
305 return optional_info;
306
307 Address vtable_addr_resolved;
308 SymbolContext sc;
309 Symbol *symbol = nullptr;
310
311 if (!target.ResolveLoadAddress(vtable_address, vtable_addr_resolved))
312 return optional_info;
313
315 vtable_addr_resolved, eSymbolContextEverything, sc);
316 symbol = sc.symbol;
317
318 if (symbol == nullptr)
319 return optional_info;
320
321 llvm::StringRef vtable_name(symbol->GetName().GetStringRef());
322 bool found_expected_start_string =
323 vtable_name.starts_with("vtable for std::__1::__function::__func<");
324
325 if (!found_expected_start_string)
326 return optional_info;
327
328 // Given case 1 or 3 we have a vtable name, we are want to extract the first
329 // template parameter
330 //
331 // ... __func<main::$_0, std::__1::allocator<main::$_0> ...
332 // ^^^^^^^^^
333 //
334 // We could see names such as:
335 // main::$_0
336 // Bar::add_num2(int)::'lambda'(int)
337 // Bar
338 //
339 // We do this by find the first < and , and extracting in between.
340 //
341 // This covers the case of the lambda known at compile time.
342 size_t first_open_angle_bracket = vtable_name.find('<') + 1;
343 size_t first_comma = vtable_name.find(',');
344
345 llvm::StringRef first_template_parameter =
346 vtable_name.slice(first_open_angle_bracket, first_comma);
347
348 Address function_address_resolved;
349
350 // Setup for cases 2, 4 and 5 we have a pointer to a function after the
351 // vtable. We will use a process of elimination to drop through each case
352 // and obtain the data we need.
353 if (target.ResolveLoadAddress(possible_function_address,
354 function_address_resolved)) {
356 function_address_resolved, eSymbolContextEverything, sc);
357 symbol = sc.symbol;
358 }
359
360 // These conditions are used several times to simplify statements later on.
361 bool has_invoke =
362 (symbol ? symbol->GetName().GetStringRef().contains("__invoke") : false);
363 auto calculate_symbol_context_helper = [](auto &t,
364 SymbolContextList &sc_list) {
365 SymbolContext sc;
366 t->CalculateSymbolContext(&sc);
367 sc_list.Append(sc);
368 };
369
370 // Case 2
371 if (has_invoke) {
373 calculate_symbol_context_helper(symbol, scl);
374
375 return line_entry_helper(target, scl[0], symbol, first_template_parameter,
376 has_invoke);
377 }
378
379 // Case 4 or 5
380 if (symbol && !symbol->GetName().GetStringRef().starts_with("vtable for") &&
381 !contains_lambda_identifier(first_template_parameter) && !has_invoke) {
382 optional_info.callable_case =
384 optional_info.callable_address = function_address_resolved;
385 optional_info.callable_symbol = *symbol;
386
387 return optional_info;
388 }
389
390 std::string func_to_match = first_template_parameter.str();
391
392 auto it = CallableLookupCache.find(func_to_match);
393 if (it != CallableLookupCache.end())
394 return it->second;
395
397
398 CompileUnit *vtable_cu =
399 vtable_first_entry_resolved.CalculateSymbolContextCompileUnit();
400 llvm::StringRef name_to_use = func_to_match;
401
402 // Case 3, we have a callable object instead of a lambda
403 //
404 // TODO
405 // We currently don't support this case a callable object may have multiple
406 // operator()() varying on const/non-const and number of arguments and we
407 // don't have a way to currently distinguish them so we will bail out now.
408 if (!contains_lambda_identifier(name_to_use))
409 return optional_info;
410
411 if (vtable_cu && !has_invoke) {
412 lldb::FunctionSP func_sp =
413 vtable_cu->FindFunction([name_to_use](const FunctionSP &f) {
414 auto name = f->GetName().GetStringRef();
415 if (name.starts_with(name_to_use) && name.contains("operator"))
416 return true;
417
418 return false;
419 });
420
421 if (func_sp) {
422 calculate_symbol_context_helper(func_sp, scl);
423 }
424 }
425
426 if (symbol == nullptr)
427 return optional_info;
428
429 // Case 1 or 3
430 if (scl.GetSize() >= 1) {
431 optional_info = line_entry_helper(target, scl[0], symbol,
432 first_template_parameter, has_invoke);
433 }
434
435 CallableLookupCache[func_to_match] = optional_info;
436
437 return optional_info;
438}
439
442 bool stop_others) {
443 ThreadPlanSP ret_plan_sp;
444
445 lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
446
447 TargetSP target_sp(thread.CalculateTarget());
448
449 if (!target_sp->HasLoadedSections())
450 return ret_plan_sp;
451
452 Address pc_addr_resolved;
453 SymbolContext sc;
454 Symbol *symbol;
455
456 if (!target_sp->ResolveLoadAddress(curr_pc, pc_addr_resolved))
457 return ret_plan_sp;
458
459 target_sp->GetImages().ResolveSymbolContextForAddress(
460 pc_addr_resolved, eSymbolContextEverything, sc);
461 symbol = sc.symbol;
462
463 if (symbol == nullptr)
464 return ret_plan_sp;
465
466 llvm::StringRef function_name(symbol->GetName().GetCString());
467
468 // Handling the case where we are attempting to step into std::function.
469 // The behavior will be that we will attempt to obtain the wrapped
470 // callable via FindLibCppStdFunctionCallableInfo() and if we find it we
471 // will return a ThreadPlanRunToAddress to the callable. Therefore we will
472 // step into the wrapped callable.
473 //
474 bool found_expected_start_string =
475 function_name.starts_with("std::__1::function<");
476
477 if (!found_expected_start_string)
478 return ret_plan_sp;
479
480 AddressRange range_of_curr_func;
481 sc.GetAddressRange(eSymbolContextEverything, 0, false, range_of_curr_func);
482
483 StackFrameSP frame = thread.GetStackFrameAtIndex(0);
484
485 if (frame) {
486 Address func_start_address =
487 sc.function ? sc.function->GetAddress() : symbol->GetAddress();
488 lldb::addr_t func_start =
489 func_start_address.GetLoadAddress(target_sp.get());
490
491 if (func_start == LLDB_INVALID_ADDRESS)
492 return ret_plan_sp;
493
494 // Advance past the prologue if we stopped there.
495 uint32_t prologue_size = sc.function ? sc.function->GetPrologueByteSize()
496 : symbol->GetPrologueByteSize();
497 if (curr_pc < func_start + prologue_size) {
498 func_start_address.Slide(prologue_size);
499 return std::make_shared<ThreadPlanRunToAddress>(
500 thread, func_start_address, stop_others);
501 }
502
503 ValueObjectSP value_sp = frame->FindVariable(g_this);
504
507
509 value_sp->GetValueIsValid()) {
510 // We found the std::function wrapped callable and we have its address.
511 // We now create a ThreadPlan to run to the callable.
512 ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
513 thread, callable_info.callable_address, stop_others);
514 return ret_plan_sp;
515 } else {
516 // We are in std::function but we could not obtain the callable.
517 // We create a ThreadPlan to keep stepping through using the address range
518 // of the current function.
519 ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
520 thread, range_of_curr_func, sc, std::string(), eOnlyThisThread,
522 return ret_plan_sp;
523 }
524 }
525
526 return ret_plan_sp;
527}
528
530 llvm::StringRef mangled_name =
532 // Virtual function overriding from a non-virtual base use a "Th" prefix.
533 // Virtual function overriding from a virtual base must use a "Tv" prefix.
534 // Virtual function overriding thunks with covariant returns use a "Tc"
535 // prefix.
536 return mangled_name.starts_with("_ZTh") || mangled_name.starts_with("_ZTv") ||
537 mangled_name.starts_with("_ZTc");
538}
539
541 const bool check_cxx = true;
542 const bool check_objc = false;
543 return in_value.GetCompilerType().IsPossibleDynamicType(nullptr, check_cxx,
544 check_objc);
545}
546
548 ValueObject &in_value, lldb::DynamicValueType use_dynamic,
549 TypeAndOrName &class_type_or_name, Address &dynamic_address,
550 Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
551 class_type_or_name.Clear();
552 value_type = Value::ValueType::Scalar;
553
554 if (!CouldHaveDynamicValue(in_value))
555 return false;
556
557 llvm::Expected<VTableInfoEntry> entry =
558 GetVTableInfoEntry(in_value, /*check_type=*/false);
559 if (!entry) {
560 llvm::consumeError(entry.takeError());
561 return false;
562 }
563
564 return entry->runtime->GetDynamicTypeAndAddress(
565 in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address);
566}
567
570 ValueObject &static_value) {
571 CompilerType static_type(static_value.GetCompilerType());
572 Flags static_type_flags(static_type.GetTypeInfo());
573
574 TypeAndOrName ret(type_and_or_name);
575 if (type_and_or_name.HasType()) {
576 // The type will always be the type of the dynamic object. If our parent's
577 // type was a pointer, then our type should be a pointer to the type of the
578 // dynamic object. If a reference, then the original type should be
579 // okay...
580 CompilerType orig_type = type_and_or_name.GetCompilerType();
581 CompilerType corrected_type = orig_type;
582 if (static_type_flags.AllSet(eTypeIsPointer))
583 corrected_type = orig_type.GetPointerType();
584 else if (static_type_flags.AllSet(eTypeIsReference))
585 corrected_type = orig_type.GetLValueReferenceType();
586 ret.SetCompilerType(corrected_type);
587 } else {
588 // If we are here we need to adjust our dynamic type name to include the
589 // correct & or * symbol
590 std::string corrected_name(type_and_or_name.GetName().GetCString());
591 if (static_type_flags.AllSet(eTypeIsPointer))
592 corrected_name.append(" *");
593 else if (static_type_flags.AllSet(eTypeIsReference))
594 corrected_name.append(" &");
595 // the parent type should be a correctly pointer'ed or referenc'ed type
596 ret.SetCompilerType(static_type);
597 ret.SetName(corrected_name.c_str());
598 }
599 return ret;
600}
601
604 lldb::LanguageType language) {
605 if (language == eLanguageTypeC_plus_plus ||
606 language == eLanguageTypeC_plus_plus_03 ||
607 language == eLanguageTypeC_plus_plus_11 ||
608 language == eLanguageTypeC_plus_plus_14)
609 return new CPPLanguageRuntime(process);
610 else
611 return nullptr;
612}
613
616 GetPluginNameStatic(), "C++ language runtime", CreateInstance,
617 [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
618 return CommandObjectSP(new CommandObjectCPlusPlus(interpreter));
619 });
620}
621
625
626llvm::Expected<LanguageRuntime::VTableInfo>
628 llvm::Expected<VTableInfoEntry> entry =
629 GetVTableInfoEntry(in_value, check_type);
630 if (!entry)
631 return entry.takeError();
632 return entry->info;
633}
634
637 bool catch_bp, bool throw_bp) {
638 return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false);
639}
640
643 bool catch_bp, bool throw_bp,
644 bool for_expressions) {
645 std::vector<const char *> exception_names;
646 for (const auto &runtime : m_abi_runtimes)
647 runtime->AppendExceptionBreakpointFunctions(exception_names, catch_bp,
648 throw_bp, for_expressions);
649
651 bkpt, exception_names.data(), exception_names.size(),
652 eFunctionNameTypeBase, eLanguageTypeUnknown, 0, eLazyBoolNo));
653
654 return resolver_sp;
655}
656
658 Target &target = m_process->GetTarget();
659
660 FileSpecList filter_modules;
661 for (const auto &runtime : m_abi_runtimes)
662 runtime->AppendExceptionBreakpointFilterModules(filter_modules, target);
663
664 return target.GetSearchFilterForModuleList(&filter_modules);
665}
666
668 bool catch_bp, bool throw_bp, bool for_expressions, bool is_internal) {
669 Target &target = m_process->GetTarget();
670 FileSpecList filter_modules;
671 BreakpointResolverSP exception_resolver_sp =
672 CreateExceptionResolver(nullptr, catch_bp, throw_bp, for_expressions);
674 const bool hardware = false;
675 const bool resolve_indirect_functions = false;
676 return target.CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal,
677 hardware, resolve_indirect_functions);
678}
679
681 if (!m_process)
682 return;
683
684 const bool catch_bp = false;
685 const bool throw_bp = true;
686 const bool is_internal = true;
687 const bool for_expressions = true;
688
689 // For the exception breakpoints set by the Expression parser, we'll be a
690 // little more aggressive and stop at exception allocation as well.
691
693 m_cxx_exception_bp_sp->SetEnabled(true);
694 } else {
696 catch_bp, throw_bp, for_expressions, is_internal);
698 m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
699 }
700}
701
703 if (!m_process)
704 return;
705
707 m_cxx_exception_bp_sp->SetEnabled(false);
708 }
709}
710
714
716 lldb::StopInfoSP stop_reason) {
717 if (!m_process)
718 return false;
719
720 if (!stop_reason || stop_reason->GetStopReason() != eStopReasonBreakpoint)
721 return false;
722
723 uint64_t break_site_id = stop_reason->GetValue();
724 return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
725 break_site_id, m_cxx_exception_bp_sp->GetID());
726}
727
730 for (const auto &runtime : m_abi_runtimes) {
731 ValueObjectSP valobj = runtime->GetExceptionObjectForThread(thread_sp);
732 if (valobj)
733 return valobj;
734 }
735 return {};
736}
737
738static llvm::Error TypeHasVTable(CompilerType type) {
739 // Check to make sure the class has a vtable.
740 CompilerType original_type = type;
741 if (type.IsPointerOrReferenceType()) {
742 CompilerType pointee_type = type.GetPointeeType();
743 if (pointee_type)
744 type = pointee_type;
745 }
746
747 // Make sure this is a class or a struct first by checking the type class
748 // bitfield that gets returned.
749 if ((type.GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
750 return llvm::createStringError(
751 std::errc::invalid_argument,
752 "type \"%s\" is not a class or struct or a pointer to one",
753 original_type.GetTypeName().AsCString("<invalid>"));
754 }
755
756 // Check if the type has virtual functions by asking it if it is polymorphic.
757 if (!type.IsPolymorphicClass()) {
758 return llvm::createStringError(std::errc::invalid_argument,
759 "type \"%s\" doesn't have a vtable",
760 type.GetTypeName().AsCString("<invalid>"));
761 }
762 return llvm::Error::success();
763}
764
765// This function can accept both pointers or references to classes as well as
766// instances of classes. If you are using this function during dynamic type
767// detection, only valid ValueObjects that return true to
768// CouldHaveDynamicValue(...) should call this function and \a check_type
769// should be set to false. This function is also used by ValueObjectVTable
770// and is can pass in instances of classes which is not suitable for dynamic
771// type detection, these cases should pass true for \a check_type.
772llvm::Expected<CPPLanguageRuntime::VTableInfoEntry>
774
775 CompilerType type = in_value.GetCompilerType();
776 if (check_type) {
777 if (llvm::Error err = TypeHasVTable(type))
778 return std::move(err);
779 }
780 ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
781 Process *process = exe_ctx.GetProcessPtr();
782 if (process == nullptr)
783 return llvm::createStringError(std::errc::invalid_argument,
784 "invalid process");
785
786 auto [original_ptr, address_type] =
788 ? in_value.GetPointerValue()
789 : in_value.GetAddressOf(/*scalar_is_load_address=*/true);
790 if (original_ptr == LLDB_INVALID_ADDRESS || address_type != eAddressTypeLoad)
791 return llvm::createStringError(std::errc::invalid_argument,
792 "failed to get the address of the value");
793
794 llvm::Expected<lldb::addr_t> vtable_load_addr_or_err =
795 process->ReadPointerFromMemory(original_ptr);
796 if (!vtable_load_addr_or_err)
797 return vtable_load_addr_or_err.takeError();
798 lldb::addr_t vtable_load_addr = *vtable_load_addr_or_err;
799
800 // The vtable load address can have authentication bits with
801 // AArch64 targets on Darwin.
802 vtable_load_addr = process->FixDataAddress(vtable_load_addr);
803
804 // Find the symbol that contains the "vtable_load_addr" address
805 Address vtable_addr;
806 if (!process->GetTarget().ResolveLoadAddress(vtable_load_addr, vtable_addr))
807 return llvm::createStringError(std::errc::invalid_argument,
808 "failed to resolve vtable pointer 0x%" PRIx64
809 "to a section",
810 vtable_load_addr);
811
812 // Check our cache first to see if we already have this info
813 {
814 auto vtable_info_map = m_vtable_info_map.Lock();
815 auto pos = vtable_info_map->find(vtable_addr);
816 if (pos != vtable_info_map->end())
817 return pos->second;
818 }
819
820 Symbol *symbol = vtable_addr.CalculateSymbolContextSymbol();
821 if (symbol == nullptr)
822 return llvm::createStringError(std::errc::invalid_argument,
823 "no symbol found for 0x%" PRIx64,
824 vtable_load_addr);
825
826 Mangled &mangled = symbol->GetMangled();
827 Log *log = GetLog(LLDBLog::Object);
828 for (const auto &runtime : m_abi_runtimes) {
829 if (runtime->IsVTableSymbol(symbol->GetMangled())) {
830 LLDB_LOG(log, "{0:x16} ({1}): symbol='{2}' matches {3}", original_ptr,
831 in_value.GetTypeName(), mangled.GetDemangledName(),
832 runtime->GetName());
833
834 VTableInfoEntry entry{
835 /*info=*/VTableInfo{vtable_addr, symbol},
836 /*runtime=*/runtime.get(),
837 };
838 (*m_vtable_info_map.Lock())[vtable_addr] = entry;
839 return entry;
840 }
841 }
842 return llvm::createStringError(std::errc::invalid_argument,
843 "symbol found that contains 0x%" PRIx64
844 " is not a vtable symbol",
845 vtable_load_addr);
846}
static ConstString g_promise
static ConstString g_coro_frame
bool contains_lambda_identifier(llvm::StringRef &str_ref)
static ConstString g_this
static llvm::Error TypeHasVTable(CompilerType type)
CPPLanguageRuntime::LibCppStdFunctionCallableInfo line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol, llvm::StringRef first_template_param_sref, bool has_invoke)
static char ID
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
#define LLDB_SCOPED_TIMER()
Definition Timer.h:88
A frame recognizer that is installed to hide libc++ implementation details from the backtrace.
lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame_sp) override
RecognizedStackFrameSP m_hidden_frame
std::array< RegularExpression, 2 > m_hidden_regex
std::string GetName() override
A section + offset based address range class.
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:303
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition Address.cpp:328
bool Slide(int64_t offset)
Definition Address.h:446
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const
Definition Address.cpp:902
CompileUnit * CalculateSymbolContextCompileUnit() const
Definition Address.cpp:846
Symbol * CalculateSymbolContextSymbol() const
Definition Address.cpp:888
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:465
"lldb/Breakpoint/BreakpointResolverName.h" This class sets breakpoints on a given function name,...
llvm::Expected< LanguageRuntime::VTableInfo > GetVTableInfo(ValueObject &in_value, bool check_type) override
Get the vtable information for a given value.
TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override
bool CouldHaveDynamicValue(ValueObject &in_value) override
lldb::BreakpointSP CreateExceptionBreakpoint(bool catch_bp, bool throw_bp, bool for_expressions, bool is_internal)
static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language)
llvm::Error GetObjectDescription(Stream &str, ValueObject &object) override
Guarded< VTableInfoMap, std::mutex > m_vtable_info_map
lldb::SearchFilterSP CreateExceptionSearchFilter() override
lldb::ValueObjectSP GetExceptionObjectForThread(lldb::ThreadSP thread_sp) override
llvm::Expected< VTableInfoEntry > GetVTableInfoEntry(ValueObject &in_value, bool check_type)
bool IsSymbolARuntimeThunk(const Symbol &symbol) override
LibCppStdFunctionCallableInfo FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp)
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override
Obtain a ThreadPlan to get us into C++ constructs such as std::function.
lldb::BreakpointResolverSP CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, bool throw_bp) override
bool IsAllowedRuntimeValue(llvm::StringRef name) override
Identify whether a name is a runtime value that should not be hidden by from the user interface.
OperatorStringToCallableInfoMap CallableLookupCache
static llvm::StringRef GetPluginNameStatic()
std::vector< std::unique_ptr< CommonABIRuntime > > m_abi_runtimes
bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type, llvm::ArrayRef< uint8_t > &local_buffer) override
This call should return true if it could set the name and/or the type Sets address to the address of ...
bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override
A class that describes a compilation unit.
Definition CompileUnit.h:43
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.
Generic representation of a type in a programming language.
bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, bool check_objc) const
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
lldb::TypeClass GetTypeClass() const
CompilerType GetLValueReferenceType() const
Return a new CompilerType that is a L value reference to this type if this type is valid and the type...
ConstString GetTypeName(bool BaseOnly=false) const
CompilerType GetPointeeType() const
If this type is a pointer type, return the type that the pointer points to, else return an invalid ty...
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
bool IsPointerOrReferenceType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Process * GetProcessPtr() const
Returns a pointer to the process object.
A file collection class.
A class to manage flags.
Definition Flags.h:22
bool AllSet(ValueType mask) const
Test if all bits in mask are 1 in the current flags.
Definition Flags.h:83
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition Function.h:439
uint32_t GetPrologueByteSize()
Get the size of the prologue instructions for this function.
Definition Function.cpp:592
A class that handles mangled names.
Definition Mangled.h:36
@ ePreferDemangledWithoutArguments
Definition Mangled.h:41
ConstString GetMangledName() const
Mangled name get accessor.
Definition Mangled.h:169
ConstString GetDemangledName() const
Demangled name get accessor.
Definition Mangled.cpp:238
uint32_t ResolveSymbolContextForAddress(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) const
Resolve the symbol context for the given address. (const Address&,uint32_t,SymbolContext&)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
Definition Process.h:369
lldb::addr_t FixDataAddress(lldb::addr_t pc)
Definition Process.cpp:6355
llvm::Expected< lldb::addr_t > ReadPointerFromMemory(lldb::addr_t vm_addr)
Definition Process.cpp:2551
uint32_t GetAddressByteSize() const
Definition Process.cpp:3973
const lldb::ABISP & GetABI()
Definition Process.cpp:1529
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1270
This class provides extra information about a stack frame that was provided by a specific stack frame...
Process * m_process
Definition Runtime.h:29
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, std::string module, std::vector< ConstString > symbols, Mangled::NamePreference symbol_mangling, bool first_instruction_only=true)
Add a new recognizer that triggers on a given symbol name.
A base class for frame recognizers.
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
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.
Symbol * symbol
The Symbol for a given query.
Address GetFunctionOrSymbolAddress() const
Get the address of the function or symbol represented by this symbol context.
Mangled & GetMangled()
Definition Symbol.h:162
ConstString GetName() const
Definition Symbol.cpp:615
Address GetAddress() const
Definition Symbol.h:98
uint32_t GetPrologueByteSize()
Definition Symbol.cpp:349
lldb::SearchFilterSP GetSearchFilterForModuleList(const FileSpecList *containingModuleList)
Definition Target.cpp:729
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
Definition Target.cpp:3530
StackFrameRecognizerManager & GetFrameRecognizerManager()
Definition Target.h:2032
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition Target.cpp:528
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1283
const ArchSpec & GetArchitecture() const
Definition Target.h:1325
Sometimes you can find the name of the type corresponding to an object, but we don't have debug infor...
void SetName(ConstString type_name)
ConstString GetName() const
void SetCompilerType(CompilerType compiler_type)
virtual ConstString GetTypeName()
CompilerType GetCompilerType()
const ExecutionContextRef & GetExecutionContextRef() const
virtual AddrAndType GetAddressOf(bool scalar_is_load_address=true)
ValueType
Type that describes Value::m_value.
Definition Value.h:42
@ Scalar
A raw scalar value.
Definition Value.h:46
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
void RegisterVerboseTrapFrameRecognizer(Process &process)
@ eAddressTypeLoad
Address is an address as in the current target inferior process.
std::shared_ptr< lldb_private::Function > FunctionSP
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::RecognizedStackFrame > RecognizedStackFrameSP
std::shared_ptr< lldb_private::SearchFilter > SearchFilterSP
std::shared_ptr< lldb_private::BreakpointResolver > BreakpointResolverSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
LanguageType
Programming language type.
@ eLanguageTypeC_plus_plus_14
ISO C++:2014.
@ eLanguageTypeC_plus_plus_03
ISO C++:2003.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC_plus_plus_11
ISO C++:2011.
@ eLanguageTypeC_plus_plus
ISO C++:1998.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::StackFrameRecognizer > StackFrameRecognizerSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
uint64_t addr_t
Definition lldb-types.h:80
@ eStopReasonBreakpoint
std::shared_ptr< lldb_private::Target > TargetSP
bool ShouldHide() override
Controls whether this frame should be filtered out when displaying backtraces, for example.
A line table entry class.
Definition LineEntry.h:21