From 19128792e2aa320c1a149f7f93638cbd7f3c83c6 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Sun, 12 Feb 2023 01:49:07 +0000 Subject: [PATCH] Reland "[lldb][DWARFASTParserClang] Attach linkage name to ctors/dtors if missing" This relands the commit previously reverted in `d2cc2c5610ffa78736aa99512bc85a85417efb0a` due to failures on Linux when debugging split-debug-info enabled executables. The problem was we called `SymbolFileDWARF::FindFunctions` directly instead of `Module::FindFunctions` which resulted in a nullptr dereference because the backing `SymbolFileDWARFDwo` didn't have an index attached to it. The relanded version calls `Module::FindFunctions` instead. Differential Revision: https://reviews.llvm.org/D143652 --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 43 ++++++++++++++++++++++ .../lang/cpp/external_ctor_dtor_lookup/Makefile | 3 ++ .../TestExternalCtorDtorLookup.py | 31 ++++++++++++++++ .../API/lang/cpp/external_ctor_dtor_lookup/lib.h | 12 ++++++ .../lang/cpp/external_ctor_dtor_lookup/main.cpp | 14 +++++++ 5 files changed, 103 insertions(+) create mode 100644 lldb/test/API/lang/cpp/external_ctor_dtor_lookup/Makefile create mode 100644 lldb/test/API/lang/cpp/external_ctor_dtor_lookup/TestExternalCtorDtorLookup.py create mode 100644 lldb/test/API/lang/cpp/external_ctor_dtor_lookup/lib.h create mode 100644 lldb/test/API/lang/cpp/external_ctor_dtor_lookup/main.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 4429b4f..8401d64 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -888,6 +888,46 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes &attrs) { return clang::CC_C; } +/// Given a DIE with an external definition (and thus no linkage name) +/// find the definitions by lookup into the DWARF name index. +/// We check the DW_AT_specification for each DIE in the index with +/// the same name as the specified 'die' until we find one that references +/// 'die'. Then return that linkage name. If no such DIE is found in the index, +/// returns nullptr. +static char const *FindLinkageName(DWARFDIE die) { + auto *dwarf = die.GetDWARF(); + if (!dwarf) + return nullptr; + + ConstString func_name(die.GetName()); + if (!func_name) + return nullptr; + + SymbolContextList sc_list; + Module::LookupInfo lookup_info(func_name, + FunctionNameType::eFunctionNameTypeMethod | + FunctionNameType::eFunctionNameTypeFull, + LanguageType::eLanguageTypeUnknown); + dwarf->GetObjectFile()->GetModule()->FindFunctions(lookup_info, {}, {}, + sc_list); + + for (auto const &sc : sc_list.SymbolContexts()) { + if (auto *func = sc.function) { + auto func_die = dwarf->GetDIE(func->GetID()); + if (!func_die.IsValid()) + continue; + + auto spec_die = + func_die.GetAttributeValueAsReferenceDIE(DW_AT_specification); + if (spec_die.IsValid() && spec_die == die) { + return func->GetMangled().GetMangledName().AsCString(); + } + } + } + + return nullptr; +} + TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs) { Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); @@ -1116,6 +1156,9 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, if (attrs.accessibility == eAccessNone) attrs.accessibility = eAccessPublic; + if (!attrs.mangled_name && attrs.storage == clang::SC_Extern) + attrs.mangled_name = FindLinkageName(die); + clang::CXXMethodDecl *cxx_method_decl = m_ast.AddMethodToCXXRecordType( class_opaque_type.GetOpaqueQualType(), diff --git a/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/Makefile b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/Makefile new file mode 100644 index 0000000..eba1547 --- /dev/null +++ b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/TestExternalCtorDtorLookup.py b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/TestExternalCtorDtorLookup.py new file mode 100644 index 0000000..e436252 --- /dev/null +++ b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/TestExternalCtorDtorLookup.py @@ -0,0 +1,31 @@ +""" +Test that we can constructors/destructors +without a linkage name because they are +marked DW_AT_external and the fallback +mangled-name-guesser in LLDB doesn't account +for ABI tags. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class ExternalCtorDtorLookupTestCase(TestBase): + + @skipIfWindows + def test(self): + self.build() + lldbutil.run_to_source_breakpoint(self, 'b\.getWrapper\(\)', + lldb.SBFileSpec('main.cpp', False)) + + self.expect_expr('b.sinkWrapper(b.getWrapper())', result_type='int', result_value='-1') + self.filecheck("target module dump ast", __file__) +# CHECK: ClassTemplateSpecializationDecl {{.*}} class Wrapper definition +# CHECK: |-TemplateArgument type 'Foo' +# CHECK: | `-RecordType {{.*}} 'Foo' +# CHECK: | `-CXXRecord {{.*}} 'Foo' +# CHECK: |-CXXConstructorDecl {{.*}} Wrapper 'void ()' +# CHECK-NEXT: | `-AsmLabelAttr {{.*}} Implicit "_ZN7WrapperI3Foo{{.*}}testEv" +# CHECK-NEXT: `-CXXDestructorDecl {{.*}} ~Wrapper 'void ()' +# CHECK-NEXT: `-AsmLabelAttr {{.*}} Implicit "_ZN7WrapperI3Foo{{.*}}testEv" diff --git a/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/lib.h b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/lib.h new file mode 100644 index 0000000..9664068 --- /dev/null +++ b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/lib.h @@ -0,0 +1,12 @@ +#ifndef LIB_H_IN +#define LIB_H_IN + +template class Wrapper { +public: + [[gnu::abi_tag("test")]] Wrapper(){}; + + [[gnu::abi_tag("test")]] ~Wrapper(){}; +}; + +#endif // _H_IN + diff --git a/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/main.cpp b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/main.cpp new file mode 100644 index 0000000..3904646 --- /dev/null +++ b/lldb/test/API/lang/cpp/external_ctor_dtor_lookup/main.cpp @@ -0,0 +1,14 @@ +#include "lib.h" + +struct Foo {}; + +struct Bar { + Wrapper getWrapper() { return Wrapper(); } + int sinkWrapper(Wrapper) { return -1; } +}; + +int main() { + Bar b; + return b.sinkWrapper(b.getWrapper()); +} + -- 2.7.4