18#include "llvm/ADT/StringRef.h"
76 std::string GetName() override {
return "libc++ frame recognizer"; }
82 const auto &sc = frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
88 if (!r.Execute(sc.function->GetNameNoArguments()))
96 thread_sp->GetStackFrameAtIndex(frame_sp->GetFrameIndex() + 1);
99 const auto &parent_sc =
100 parent_frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
101 if (!parent_sc.function)
103 if (parent_sc.function->GetNameNoArguments().GetStringRef().starts_with(
117 std::make_shared<RegularExpression>(
"^std::__[^:]*::"),
132 return llvm::createStringError(
"C++ does not support object descriptions");
139 return llvm::createStringError(
"C++ does not support object descriptions");
143 return str_ref.contains(
"$_") || str_ref.contains(
"'lambda'");
148 llvm::StringRef first_template_param_sref,
bool has_invoke) {
162 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
163 LibCppStdFunctionCallableCase::Lambda;
166 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
167 LibCppStdFunctionCallableCase::CallableObject;
175 return optional_info;
186 return optional_info;
220 ValueObjectSP member_f_(valobj_sp->GetChildMemberWithName(
"__f_"));
223 ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName(
"__f_"));
226 member_f_ = sub_member_f_;
230 return optional_info;
232 lldb::addr_t member_f_pointer_value = member_f_->GetValueAsUnsigned(0);
236 if (!member_f_pointer_value)
237 return optional_info;
242 if (process ==
nullptr)
243 return optional_info;
255 vtable_address = abi_sp->FixCodeAddress(vtable_address);
258 return optional_info;
264 vtable_address_first_entry =
265 abi_sp->FixCodeAddress(vtable_address_first_entry);
268 return optional_info;
270 lldb::addr_t address_after_vtable = member_f_pointer_value + address_size;
277 possible_function_address =
278 abi_sp->FixCodeAddress(possible_function_address);
281 return optional_info;
286 return optional_info;
288 Address vtable_first_entry_resolved;
291 vtable_first_entry_resolved))
292 return optional_info;
299 return optional_info;
302 vtable_addr_resolved, eSymbolContextEverything, sc);
305 if (symbol ==
nullptr)
306 return optional_info;
309 bool found_expected_start_string =
310 vtable_name.starts_with(
"vtable for std::__1::__function::__func<");
312 if (!found_expected_start_string)
313 return optional_info;
329 size_t first_open_angle_bracket = vtable_name.find(
'<') + 1;
330 size_t first_comma = vtable_name.find(
',');
332 llvm::StringRef first_template_parameter =
333 vtable_name.slice(first_open_angle_bracket, first_comma);
335 Address function_address_resolved;
341 function_address_resolved)) {
343 function_address_resolved, eSymbolContextEverything, sc);
349 (symbol ? symbol->
GetName().GetStringRef().contains(
"__invoke") :
false);
350 auto calculate_symbol_context_helper = [](
auto &t,
353 t->CalculateSymbolContext(&sc);
360 calculate_symbol_context_helper(symbol, scl);
374 return optional_info;
377 std::string func_to_match = first_template_parameter.str();
387 llvm::StringRef name_to_use = func_to_match;
396 return optional_info;
398 if (vtable_cu && !has_invoke) {
401 auto name = f->GetName().GetStringRef();
402 if (name.starts_with(name_to_use) && name.contains(
"operator"))
409 calculate_symbol_context_helper(func_sp, scl);
413 if (symbol ==
nullptr)
414 return optional_info;
419 first_template_parameter, has_invoke);
424 return optional_info;
432 lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
434 TargetSP target_sp(thread.CalculateTarget());
436 if (!target_sp->HasLoadedSections())
443 if (!target_sp->ResolveLoadAddress(curr_pc, pc_addr_resolved))
446 target_sp->GetImages().ResolveSymbolContextForAddress(
447 pc_addr_resolved, eSymbolContextEverything, sc);
450 if (symbol ==
nullptr)
461 bool found_expected_start_string =
462 function_name.starts_with(
"std::__1::function<");
464 if (!found_expected_start_string)
468 sc.
GetAddressRange(eSymbolContextEverything, 0,
false, range_of_curr_func);
484 if (curr_pc < func_start + prologue_size) {
485 func_start_address.
Slide(prologue_size);
486 return std::make_shared<ThreadPlanRunToAddress>(
487 thread, func_start_address, stop_others);
496 value_sp->GetValueIsValid()) {
499 ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
506 ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
517 llvm::StringRef mangled_name =
523 return mangled_name.starts_with(
"_ZTh") || mangled_name.starts_with(
"_ZTv") ||
524 mangled_name.starts_with(
"_ZTc");
528 const bool check_cxx =
true;
529 const bool check_objc =
false;
538 class_type_or_name.
Clear();
544 llvm::Expected<VTableInfoEntry> entry =
547 llvm::consumeError(entry.takeError());
552 in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address,
563 if (type_and_or_name.
HasType()) {
570 if (static_type_flags.
AllSet(eTypeIsPointer))
572 else if (static_type_flags.
AllSet(eTypeIsReference))
579 if (static_type_flags.
AllSet(eTypeIsPointer))
580 corrected_name.append(
" *");
581 else if (static_type_flags.
AllSet(eTypeIsReference))
582 corrected_name.append(
" &");
585 ret.
SetName(corrected_name.c_str());
614llvm::Expected<LanguageRuntime::VTableInfo>
616 llvm::Expected<VTableInfoEntry> entry =
619 return entry.takeError();
625 bool catch_bp,
bool throw_bp) {
631 bool catch_bp,
bool throw_bp,
632 bool for_expressions) {
633 std::vector<const char *> exception_names;
635 exception_names, catch_bp, throw_bp, for_expressions);
638 bkpt, exception_names.data(), exception_names.size(),
654 bool catch_bp,
bool throw_bp,
bool for_expressions,
bool is_internal) {
660 const bool hardware =
false;
661 const bool resolve_indirect_functions =
false;
662 return target.
CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal,
663 hardware, resolve_indirect_functions);
670 const bool catch_bp =
false;
671 const bool throw_bp =
true;
672 const bool is_internal =
true;
673 const bool for_expressions =
true;
682 catch_bp, throw_bp, for_expressions, is_internal);
709 uint64_t break_site_id = stop_reason->GetValue();
710 return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
730 if ((type.
GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
731 return llvm::createStringError(
732 std::errc::invalid_argument,
733 "type \"%s\" is not a class or struct or a pointer to one",
739 return llvm::createStringError(std::errc::invalid_argument,
740 "type \"%s\" doesn't have a vtable",
743 return llvm::Error::success();
753llvm::Expected<CPPLanguageRuntime::VTableInfoEntry>
759 return std::move(err);
763 if (process ==
nullptr)
764 return llvm::createStringError(std::errc::invalid_argument,
767 auto [original_ptr, address_type] =
772 return llvm::createStringError(std::errc::invalid_argument,
773 "failed to get the address of the value");
780 return llvm::createStringError(
781 std::errc::invalid_argument,
782 "failed to read vtable pointer from memory at 0x%" PRIx64,
792 return llvm::createStringError(std::errc::invalid_argument,
793 "failed to resolve vtable pointer 0x%" PRIx64
806 if (symbol ==
nullptr)
807 return llvm::createStringError(std::errc::invalid_argument,
808 "no symbol found for 0x%" PRIx64,
818 return llvm::createStringError(std::errc::invalid_argument,
819 "symbol found that contains 0x%" PRIx64
820 " is not a vtable symbol",
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 llvm::raw_ostream & error(Stream &strm)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
#define LLDB_SCOPED_TIMER()
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.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
bool Slide(int64_t offset)
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const
CompileUnit * CalculateSymbolContextCompileUnit() const
Symbol * CalculateSymbolContextSymbol() const
"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.
std::map< Address, VTableInfoEntry > m_vtable_info_map
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
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
bool IsAllowedRuntimeValue(ConstString name) override
Identify whether a name is a runtime value that should not be hidden by from the user interface.
void ClearExceptionBreakpoints() 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
ItaniumABIRuntime m_itanium_runtime
std::mutex m_vtable_mutex
bool ExceptionBreakpointsAreSet() override
OperatorStringToCallableInfoMap CallableLookupCache
CPPLanguageRuntime(Process *process)
void SetExceptionBreakpoints() override
static llvm::StringRef GetPluginNameStatic()
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
lldb::BreakpointSP m_cxx_exception_bp_sp
A class that describes a compilation unit.
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 IsPolymorphicClass() const
bool IsPointerOrReferenceType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
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.
bool AllSet(ValueType mask) const
Test if all bits in mask are 1 in the current flags.
const Address & GetAddress() const
Return the address of the function (its entry point).
uint32_t GetPrologueByteSize()
Get the size of the prologue instructions for this function.
LanguageRuntime(Process *process)
@ ePreferDemangledWithoutArguments
ConstString GetMangledName() const
Mangled name get accessor.
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.
lldb::addr_t FixDataAddress(lldb::addr_t pc)
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
uint32_t GetAddressByteSize() const
const lldb::ABISP & GetABI()
Target & GetTarget()
Get the target object pointer for this module.
This class provides extra information about a stack frame that was provided by a specific stack frame...
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< 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.
bool Fail() const
Test for error condition.
A stream class that can stream formatted output to a file.
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.
ConstString GetName() const
Address GetAddress() const
uint32_t GetPrologueByteSize()
lldb::SearchFilterSP GetSearchFilterForModuleList(const FileSpecList *containingModuleList)
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
StackFrameRecognizerManager & GetFrameRecognizerManager()
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)
const ModuleList & GetImages() const
Get accessor for the images for this process.
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)
CompilerType GetCompilerType() const
ConstString GetName() const
void SetCompilerType(CompilerType compiler_type)
CompilerType GetCompilerType()
AddrAndType GetPointerValue()
const ExecutionContextRef & GetExecutionContextRef() const
virtual AddrAndType GetAddressOf(bool scalar_is_load_address=true)
ValueType
Type that describes Value::m_value.
@ Scalar
A raw scalar value.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
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
std::shared_ptr< lldb_private::Target > TargetSP
bool ShouldHide() override
Controls whether this frame should be filtered out when displaying backtraces, for example.
lldb::addr_t member_f_pointer_value
LineEntry callable_line_entry
LibCppStdFunctionCallableCase callable_case
A line table entry class.