19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/Error.h"
79 std::string GetName() override {
return "libc++ frame recognizer"; }
85 const auto &sc = frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
91 if (!r.Execute(sc.function->GetNameNoArguments()))
99 thread_sp->GetStackFrameAtIndex(frame_sp->GetFrameIndex() + 1);
100 if (!parent_frame_sp)
102 const auto &parent_sc =
103 parent_frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
104 if (!parent_sc.function)
106 if (parent_sc.function->GetNameNoArguments().GetStringRef().starts_with(
120 std::make_shared<RegularExpression>(
"^std::__[^:]*::"),
137 return llvm::createStringError(
"C++ does not support object descriptions");
144 return llvm::createStringError(
"C++ does not support object descriptions");
148 return str_ref.contains(
"$_") || str_ref.contains(
"'lambda'");
153 llvm::StringRef first_template_param_sref,
bool has_invoke) {
167 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
168 LibCppStdFunctionCallableCase::Lambda;
171 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
172 LibCppStdFunctionCallableCase::CallableObject;
180 return optional_info;
191 return optional_info;
225 ValueObjectSP member_f_(valobj_sp->GetChildMemberWithName(
"__f_"));
228 ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName(
"__f_"));
231 member_f_ = sub_member_f_;
235 return optional_info;
237 lldb::addr_t member_f_pointer_value = member_f_->GetValueAsUnsigned(0);
241 if (!member_f_pointer_value)
242 return optional_info;
247 if (process ==
nullptr)
248 return optional_info;
254 llvm::Expected<lldb::addr_t> vtable_address_or_err =
256 if (!vtable_address_or_err) {
257 llvm::consumeError(vtable_address_or_err.takeError());
258 return optional_info;
264 vtable_address = abi_sp->FixCodeAddress(vtable_address);
266 llvm::Expected<lldb::addr_t> vtable_address_first_entry_or_err =
268 if (!vtable_address_first_entry_or_err) {
269 llvm::consumeError(vtable_address_first_entry_or_err.takeError());
270 return optional_info;
272 lldb::addr_t vtable_address_first_entry = *vtable_address_first_entry_or_err;
275 vtable_address_first_entry =
276 abi_sp->FixCodeAddress(vtable_address_first_entry);
278 lldb::addr_t address_after_vtable = member_f_pointer_value + address_size;
281 llvm::Expected<lldb::addr_t> possible_function_address_or_err =
283 if (!possible_function_address_or_err) {
284 llvm::consumeError(possible_function_address_or_err.takeError());
285 return optional_info;
287 lldb::addr_t possible_function_address = *possible_function_address_or_err;
290 possible_function_address =
291 abi_sp->FixCodeAddress(possible_function_address);
296 return optional_info;
298 Address vtable_first_entry_resolved;
301 vtable_first_entry_resolved))
302 return optional_info;
309 return optional_info;
312 vtable_addr_resolved, eSymbolContextEverything, sc);
315 if (symbol ==
nullptr)
316 return optional_info;
319 bool found_expected_start_string =
320 vtable_name.starts_with(
"vtable for std::__1::__function::__func<");
322 if (!found_expected_start_string)
323 return optional_info;
339 size_t first_open_angle_bracket = vtable_name.find(
'<') + 1;
340 size_t first_comma = vtable_name.find(
',');
342 llvm::StringRef first_template_parameter =
343 vtable_name.slice(first_open_angle_bracket, first_comma);
345 Address function_address_resolved;
351 function_address_resolved)) {
353 function_address_resolved, eSymbolContextEverything, sc);
359 (symbol ? symbol->
GetName().GetStringRef().contains(
"__invoke") :
false);
360 auto calculate_symbol_context_helper = [](
auto &t,
363 t->CalculateSymbolContext(&sc);
370 calculate_symbol_context_helper(symbol, scl);
384 return optional_info;
387 std::string func_to_match = first_template_parameter.str();
397 llvm::StringRef name_to_use = func_to_match;
406 return optional_info;
408 if (vtable_cu && !has_invoke) {
411 auto name = f->GetName().GetStringRef();
412 if (name.starts_with(name_to_use) && name.contains(
"operator"))
419 calculate_symbol_context_helper(func_sp, scl);
423 if (symbol ==
nullptr)
424 return optional_info;
429 first_template_parameter, has_invoke);
434 return optional_info;
442 lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
444 TargetSP target_sp(thread.CalculateTarget());
446 if (!target_sp->HasLoadedSections())
453 if (!target_sp->ResolveLoadAddress(curr_pc, pc_addr_resolved))
456 target_sp->GetImages().ResolveSymbolContextForAddress(
457 pc_addr_resolved, eSymbolContextEverything, sc);
460 if (symbol ==
nullptr)
471 bool found_expected_start_string =
472 function_name.starts_with(
"std::__1::function<");
474 if (!found_expected_start_string)
478 sc.
GetAddressRange(eSymbolContextEverything, 0,
false, range_of_curr_func);
494 if (curr_pc < func_start + prologue_size) {
495 func_start_address.
Slide(prologue_size);
496 return std::make_shared<ThreadPlanRunToAddress>(
497 thread, func_start_address, stop_others);
506 value_sp->GetValueIsValid()) {
509 ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
516 ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
527 llvm::StringRef mangled_name =
533 return mangled_name.starts_with(
"_ZTh") || mangled_name.starts_with(
"_ZTv") ||
534 mangled_name.starts_with(
"_ZTc");
538 const bool check_cxx =
true;
539 const bool check_objc =
false;
548 class_type_or_name.
Clear();
554 llvm::Expected<VTableInfoEntry> entry =
557 llvm::consumeError(entry.takeError());
561 return entry->runtime->GetDynamicTypeAndAddress(
562 in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address);
572 if (type_and_or_name.
HasType()) {
579 if (static_type_flags.
AllSet(eTypeIsPointer))
581 else if (static_type_flags.
AllSet(eTypeIsReference))
588 if (static_type_flags.
AllSet(eTypeIsPointer))
589 corrected_name.append(
" *");
590 else if (static_type_flags.
AllSet(eTypeIsReference))
591 corrected_name.append(
" &");
594 ret.
SetName(corrected_name.c_str());
623llvm::Expected<LanguageRuntime::VTableInfo>
625 llvm::Expected<VTableInfoEntry> entry =
628 return entry.takeError();
634 bool catch_bp,
bool throw_bp) {
640 bool catch_bp,
bool throw_bp,
641 bool for_expressions) {
642 std::vector<const char *> exception_names;
644 runtime->AppendExceptionBreakpointFunctions(exception_names, catch_bp,
645 throw_bp, for_expressions);
648 bkpt, exception_names.data(), exception_names.size(),
659 runtime->AppendExceptionBreakpointFilterModules(filter_modules, target);
665 bool catch_bp,
bool throw_bp,
bool for_expressions,
bool is_internal) {
671 const bool hardware =
false;
672 const bool resolve_indirect_functions =
false;
673 return target.
CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal,
674 hardware, resolve_indirect_functions);
681 const bool catch_bp =
false;
682 const bool throw_bp =
true;
683 const bool is_internal =
true;
684 const bool for_expressions =
true;
693 catch_bp, throw_bp, for_expressions, is_internal);
720 uint64_t break_site_id = stop_reason->GetValue();
721 return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
728 ValueObjectSP valobj = runtime->GetExceptionObjectForThread(thread_sp);
746 if ((type.
GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
747 return llvm::createStringError(
748 std::errc::invalid_argument,
749 "type \"%s\" is not a class or struct or a pointer to one",
755 return llvm::createStringError(std::errc::invalid_argument,
756 "type \"%s\" doesn't have a vtable",
759 return llvm::Error::success();
769llvm::Expected<CPPLanguageRuntime::VTableInfoEntry>
775 return std::move(err);
779 if (process ==
nullptr)
780 return llvm::createStringError(std::errc::invalid_argument,
783 auto [original_ptr, address_type] =
788 return llvm::createStringError(std::errc::invalid_argument,
789 "failed to get the address of the value");
791 llvm::Expected<lldb::addr_t> vtable_load_addr_or_err =
793 if (!vtable_load_addr_or_err)
794 return vtable_load_addr_or_err.takeError();
795 lldb::addr_t vtable_load_addr = *vtable_load_addr_or_err;
804 return llvm::createStringError(std::errc::invalid_argument,
805 "failed to resolve vtable pointer 0x%" PRIx64
818 if (symbol ==
nullptr)
819 return llvm::createStringError(std::errc::invalid_argument,
820 "no symbol found for 0x%" PRIx64,
826 if (runtime->IsVTableSymbol(symbol->
GetMangled())) {
827 LLDB_LOG(log,
"{0:x16} ({1}): symbol='{2}' matches {3}", original_ptr,
840 return llvm::createStringError(std::errc::invalid_argument,
841 "symbol found that contains 0x%" PRIx64
842 " 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)
#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)
llvm::Expected< lldb::addr_t > ReadPointerFromMemory(lldb::addr_t vm_addr)
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.
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.