20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/Error.h"
80 std::string GetName() override {
return "libc++ frame recognizer"; }
86 const auto &sc = frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
92 if (!r.Execute(sc.function->GetNameNoArguments()))
100 thread_sp->GetStackFrameAtIndex(frame_sp->GetFrameIndex() + 1);
101 if (!parent_frame_sp)
103 const auto &parent_sc =
104 parent_frame_sp->GetSymbolContext(lldb::eSymbolContextFunction);
105 if (!parent_sc.function)
107 if (parent_sc.function->GetNameNoArguments().GetStringRef().starts_with(
121 std::make_shared<RegularExpression>(
"^std::__[^:]*::"),
140 return llvm::createStringError(
"C++ does not support object descriptions");
147 return llvm::createStringError(
"C++ does not support object descriptions");
151 return str_ref.contains(
"$_") || str_ref.contains(
"'lambda'");
156 llvm::StringRef first_template_param_sref,
bool has_invoke) {
170 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
171 LibCppStdFunctionCallableCase::Lambda;
174 optional_info.
callable_case = lldb_private::CPPLanguageRuntime::
175 LibCppStdFunctionCallableCase::CallableObject;
183 return optional_info;
194 return optional_info;
228 ValueObjectSP member_f_(valobj_sp->GetChildMemberWithName(
"__f_"));
231 ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName(
"__f_"));
234 member_f_ = sub_member_f_;
238 return optional_info;
240 lldb::addr_t member_f_pointer_value = member_f_->GetValueAsUnsigned(0);
244 if (!member_f_pointer_value)
245 return optional_info;
250 if (process ==
nullptr)
251 return optional_info;
257 llvm::Expected<lldb::addr_t> vtable_address_or_err =
259 if (!vtable_address_or_err) {
260 llvm::consumeError(vtable_address_or_err.takeError());
261 return optional_info;
267 vtable_address = abi_sp->FixCodeAddress(vtable_address);
269 llvm::Expected<lldb::addr_t> vtable_address_first_entry_or_err =
271 if (!vtable_address_first_entry_or_err) {
272 llvm::consumeError(vtable_address_first_entry_or_err.takeError());
273 return optional_info;
275 lldb::addr_t vtable_address_first_entry = *vtable_address_first_entry_or_err;
278 vtable_address_first_entry =
279 abi_sp->FixCodeAddress(vtable_address_first_entry);
281 lldb::addr_t address_after_vtable = member_f_pointer_value + address_size;
284 llvm::Expected<lldb::addr_t> possible_function_address_or_err =
286 if (!possible_function_address_or_err) {
287 llvm::consumeError(possible_function_address_or_err.takeError());
288 return optional_info;
290 lldb::addr_t possible_function_address = *possible_function_address_or_err;
293 possible_function_address =
294 abi_sp->FixCodeAddress(possible_function_address);
299 return optional_info;
301 Address vtable_first_entry_resolved;
304 vtable_first_entry_resolved))
305 return optional_info;
312 return optional_info;
315 vtable_addr_resolved, eSymbolContextEverything, sc);
318 if (symbol ==
nullptr)
319 return optional_info;
322 bool found_expected_start_string =
323 vtable_name.starts_with(
"vtable for std::__1::__function::__func<");
325 if (!found_expected_start_string)
326 return optional_info;
342 size_t first_open_angle_bracket = vtable_name.find(
'<') + 1;
343 size_t first_comma = vtable_name.find(
',');
345 llvm::StringRef first_template_parameter =
346 vtable_name.slice(first_open_angle_bracket, first_comma);
348 Address function_address_resolved;
354 function_address_resolved)) {
356 function_address_resolved, eSymbolContextEverything, sc);
362 (symbol ? symbol->
GetName().GetStringRef().contains(
"__invoke") :
false);
363 auto calculate_symbol_context_helper = [](
auto &t,
366 t->CalculateSymbolContext(&sc);
373 calculate_symbol_context_helper(symbol, scl);
387 return optional_info;
390 std::string func_to_match = first_template_parameter.str();
400 llvm::StringRef name_to_use = func_to_match;
409 return optional_info;
411 if (vtable_cu && !has_invoke) {
414 auto name = f->GetName().GetStringRef();
415 if (name.starts_with(name_to_use) && name.contains(
"operator"))
422 calculate_symbol_context_helper(func_sp, scl);
426 if (symbol ==
nullptr)
427 return optional_info;
432 first_template_parameter, has_invoke);
437 return optional_info;
445 lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
447 TargetSP target_sp(thread.CalculateTarget());
449 if (!target_sp->HasLoadedSections())
456 if (!target_sp->ResolveLoadAddress(curr_pc, pc_addr_resolved))
459 target_sp->GetImages().ResolveSymbolContextForAddress(
460 pc_addr_resolved, eSymbolContextEverything, sc);
463 if (symbol ==
nullptr)
474 bool found_expected_start_string =
475 function_name.starts_with(
"std::__1::function<");
477 if (!found_expected_start_string)
481 sc.
GetAddressRange(eSymbolContextEverything, 0,
false, range_of_curr_func);
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);
509 value_sp->GetValueIsValid()) {
512 ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
519 ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
530 llvm::StringRef mangled_name =
536 return mangled_name.starts_with(
"_ZTh") || mangled_name.starts_with(
"_ZTv") ||
537 mangled_name.starts_with(
"_ZTc");
541 const bool check_cxx =
true;
542 const bool check_objc =
false;
551 class_type_or_name.
Clear();
557 llvm::Expected<VTableInfoEntry> entry =
560 llvm::consumeError(entry.takeError());
564 return entry->runtime->GetDynamicTypeAndAddress(
565 in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address);
575 if (type_and_or_name.
HasType()) {
582 if (static_type_flags.
AllSet(eTypeIsPointer))
584 else if (static_type_flags.
AllSet(eTypeIsReference))
591 if (static_type_flags.
AllSet(eTypeIsPointer))
592 corrected_name.append(
" *");
593 else if (static_type_flags.
AllSet(eTypeIsReference))
594 corrected_name.append(
" &");
597 ret.
SetName(corrected_name.c_str());
626llvm::Expected<LanguageRuntime::VTableInfo>
628 llvm::Expected<VTableInfoEntry> entry =
631 return entry.takeError();
637 bool catch_bp,
bool throw_bp) {
643 bool catch_bp,
bool throw_bp,
644 bool for_expressions) {
645 std::vector<const char *> exception_names;
647 runtime->AppendExceptionBreakpointFunctions(exception_names, catch_bp,
648 throw_bp, for_expressions);
651 bkpt, exception_names.data(), exception_names.size(),
662 runtime->AppendExceptionBreakpointFilterModules(filter_modules, target);
668 bool catch_bp,
bool throw_bp,
bool for_expressions,
bool is_internal) {
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);
684 const bool catch_bp =
false;
685 const bool throw_bp =
true;
686 const bool is_internal =
true;
687 const bool for_expressions =
true;
696 catch_bp, throw_bp, for_expressions, is_internal);
723 uint64_t break_site_id = stop_reason->GetValue();
724 return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
731 ValueObjectSP valobj = runtime->GetExceptionObjectForThread(thread_sp);
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",
758 return llvm::createStringError(std::errc::invalid_argument,
759 "type \"%s\" doesn't have a vtable",
762 return llvm::Error::success();
772llvm::Expected<CPPLanguageRuntime::VTableInfoEntry>
778 return std::move(err);
782 if (process ==
nullptr)
783 return llvm::createStringError(std::errc::invalid_argument,
786 auto [original_ptr, address_type] =
791 return llvm::createStringError(std::errc::invalid_argument,
792 "failed to get the address of the value");
794 llvm::Expected<lldb::addr_t> vtable_load_addr_or_err =
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;
807 return llvm::createStringError(std::errc::invalid_argument,
808 "failed to resolve vtable pointer 0x%" PRIx64
815 auto pos = vtable_info_map->find(vtable_addr);
816 if (pos != vtable_info_map->end())
821 if (symbol ==
nullptr)
822 return llvm::createStringError(std::errc::invalid_argument,
823 "no symbol found for 0x%" PRIx64,
829 if (runtime->IsVTableSymbol(symbol->
GetMangled())) {
830 LLDB_LOG(log,
"{0:x16} ({1}): symbol='{2}' matches {3}", original_ptr,
842 return llvm::createStringError(std::errc::invalid_argument,
843 "symbol found that contains 0x%" PRIx64
844 " 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
llvm::Triple & GetTriple()
Architecture triple accessor.
"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
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
bool IsAllowedRuntimeValue(llvm::StringRef name) override
Identify whether a name is a runtime value that should not be hidden by from the user interface.
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, 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.
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.
const ArchSpec & GetArchitecture() const
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.