19#include "llvm/ADT/StringRef.h"
78 std::string GetName() override {
return "libc++ frame recognizer"; }
84 const auto &sc = frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
90 if (!r.Execute(sc.function->GetNameNoArguments()))
98 thread_sp->GetStackFrameAtIndex(frame_sp->GetFrameIndex() + 1);
101 const auto &parent_sc =
102 parent_frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
103 if (!parent_sc.function)
105 if (parent_sc.function->GetNameNoArguments().GetStringRef().starts_with(
119 std::make_shared<RegularExpression>(
"^std::__[^:]*::"),
136 return llvm::createStringError(
"C++ does not support object descriptions");
143 return llvm::createStringError(
"C++ does not support object descriptions");
147 return str_ref.contains(
"$_") || str_ref.contains(
"'lambda'");
152 llvm::StringRef first_template_param_sref,
bool has_invoke) {
166 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
167 LibCppStdFunctionCallableCase::Lambda;
170 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
171 LibCppStdFunctionCallableCase::CallableObject;
179 return optional_info;
190 return optional_info;
224 ValueObjectSP member_f_(valobj_sp->GetChildMemberWithName(
"__f_"));
227 ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName(
"__f_"));
230 member_f_ = sub_member_f_;
234 return optional_info;
236 lldb::addr_t member_f_pointer_value = member_f_->GetValueAsUnsigned(0);
240 if (!member_f_pointer_value)
241 return optional_info;
246 if (process ==
nullptr)
247 return optional_info;
259 vtable_address = abi_sp->FixCodeAddress(vtable_address);
262 return optional_info;
268 vtable_address_first_entry =
269 abi_sp->FixCodeAddress(vtable_address_first_entry);
272 return optional_info;
274 lldb::addr_t address_after_vtable = member_f_pointer_value + address_size;
281 possible_function_address =
282 abi_sp->FixCodeAddress(possible_function_address);
285 return optional_info;
290 return optional_info;
292 Address vtable_first_entry_resolved;
295 vtable_first_entry_resolved))
296 return optional_info;
303 return optional_info;
306 vtable_addr_resolved, eSymbolContextEverything, sc);
309 if (symbol ==
nullptr)
310 return optional_info;
313 bool found_expected_start_string =
314 vtable_name.starts_with(
"vtable for std::__1::__function::__func<");
316 if (!found_expected_start_string)
317 return optional_info;
333 size_t first_open_angle_bracket = vtable_name.find(
'<') + 1;
334 size_t first_comma = vtable_name.find(
',');
336 llvm::StringRef first_template_parameter =
337 vtable_name.slice(first_open_angle_bracket, first_comma);
339 Address function_address_resolved;
345 function_address_resolved)) {
347 function_address_resolved, eSymbolContextEverything, sc);
353 (symbol ? symbol->
GetName().GetStringRef().contains(
"__invoke") :
false);
354 auto calculate_symbol_context_helper = [](
auto &t,
357 t->CalculateSymbolContext(&sc);
364 calculate_symbol_context_helper(symbol, scl);
378 return optional_info;
381 std::string func_to_match = first_template_parameter.str();
391 llvm::StringRef name_to_use = func_to_match;
400 return optional_info;
402 if (vtable_cu && !has_invoke) {
405 auto name = f->GetName().GetStringRef();
406 if (name.starts_with(name_to_use) && name.contains(
"operator"))
413 calculate_symbol_context_helper(func_sp, scl);
417 if (symbol ==
nullptr)
418 return optional_info;
423 first_template_parameter, has_invoke);
428 return optional_info;
436 lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
438 TargetSP target_sp(thread.CalculateTarget());
440 if (!target_sp->HasLoadedSections())
447 if (!target_sp->ResolveLoadAddress(curr_pc, pc_addr_resolved))
450 target_sp->GetImages().ResolveSymbolContextForAddress(
451 pc_addr_resolved, eSymbolContextEverything, sc);
454 if (symbol ==
nullptr)
465 bool found_expected_start_string =
466 function_name.starts_with(
"std::__1::function<");
468 if (!found_expected_start_string)
472 sc.
GetAddressRange(eSymbolContextEverything, 0,
false, range_of_curr_func);
488 if (curr_pc < func_start + prologue_size) {
489 func_start_address.
Slide(prologue_size);
490 return std::make_shared<ThreadPlanRunToAddress>(
491 thread, func_start_address, stop_others);
500 value_sp->GetValueIsValid()) {
503 ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
510 ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
521 llvm::StringRef mangled_name =
527 return mangled_name.starts_with(
"_ZTh") || mangled_name.starts_with(
"_ZTv") ||
528 mangled_name.starts_with(
"_ZTc");
532 const bool check_cxx =
true;
533 const bool check_objc =
false;
542 class_type_or_name.
Clear();
548 llvm::Expected<VTableInfoEntry> entry =
551 llvm::consumeError(entry.takeError());
555 return entry->runtime->GetDynamicTypeAndAddress(
556 in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address);
566 if (type_and_or_name.
HasType()) {
573 if (static_type_flags.
AllSet(eTypeIsPointer))
575 else if (static_type_flags.
AllSet(eTypeIsReference))
582 if (static_type_flags.
AllSet(eTypeIsPointer))
583 corrected_name.append(
" *");
584 else if (static_type_flags.
AllSet(eTypeIsReference))
585 corrected_name.append(
" &");
588 ret.
SetName(corrected_name.c_str());
617llvm::Expected<LanguageRuntime::VTableInfo>
619 llvm::Expected<VTableInfoEntry> entry =
622 return entry.takeError();
628 bool catch_bp,
bool throw_bp) {
634 bool catch_bp,
bool throw_bp,
635 bool for_expressions) {
636 std::vector<const char *> exception_names;
638 runtime->AppendExceptionBreakpointFunctions(exception_names, catch_bp,
639 throw_bp, for_expressions);
642 bkpt, exception_names.data(), exception_names.size(),
653 runtime->AppendExceptionBreakpointFilterModules(filter_modules, target);
659 bool catch_bp,
bool throw_bp,
bool for_expressions,
bool is_internal) {
665 const bool hardware =
false;
666 const bool resolve_indirect_functions =
false;
667 return target.
CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal,
668 hardware, resolve_indirect_functions);
675 const bool catch_bp =
false;
676 const bool throw_bp =
true;
677 const bool is_internal =
true;
678 const bool for_expressions =
true;
687 catch_bp, throw_bp, for_expressions, is_internal);
714 uint64_t break_site_id = stop_reason->GetValue();
715 return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
722 ValueObjectSP valobj = runtime->GetExceptionObjectForThread(thread_sp);
740 if ((type.
GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
741 return llvm::createStringError(
742 std::errc::invalid_argument,
743 "type \"%s\" is not a class or struct or a pointer to one",
749 return llvm::createStringError(std::errc::invalid_argument,
750 "type \"%s\" doesn't have a vtable",
753 return llvm::Error::success();
763llvm::Expected<CPPLanguageRuntime::VTableInfoEntry>
769 return std::move(err);
773 if (process ==
nullptr)
774 return llvm::createStringError(std::errc::invalid_argument,
777 auto [original_ptr, address_type] =
782 return llvm::createStringError(std::errc::invalid_argument,
783 "failed to get the address of the value");
790 return llvm::createStringError(
791 std::errc::invalid_argument,
792 "failed to read vtable pointer from memory at 0x%" PRIx64,
802 return llvm::createStringError(std::errc::invalid_argument,
803 "failed to resolve vtable pointer 0x%" PRIx64
816 if (symbol ==
nullptr)
817 return llvm::createStringError(std::errc::invalid_argument,
818 "no symbol found for 0x%" PRIx64,
824 if (runtime->IsVTableSymbol(symbol->
GetMangled())) {
825 LLDB_LOG(log,
"{0:x16} ({1}): symbol='{2}' matches {3}", original_ptr,
838 return llvm::createStringError(std::errc::invalid_argument,
839 "symbol found that contains 0x%" PRIx64
840 " 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_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#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
std::mutex m_vtable_mutex
bool ExceptionBreakpointsAreSet() override
OperatorStringToCallableInfoMap CallableLookupCache
CPPLanguageRuntime(Process *process)
void SetExceptionBreakpoints() override
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
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)
A class that handles mangled names.
@ ePreferDemangledWithoutArguments
ConstString GetMangledName() const
Mangled name get accessor.
ConstString GetDemangledName() const
Demangled 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)
virtual ConstString GetTypeName()
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.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
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.