Skip to content

[clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable #72235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

Michael137
Copy link
Member

@Michael137 Michael137 commented Nov 14, 2023

This patch implements the DWARFv5 issue 161118.1: "DW_TAG for C++ static data members".

This will simplify LLDB's handling of static data members greatly in the long term since we no longer need to differentiate non-static from static data member declarations using non-portable heuristics.

Depends on:

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. debuginfo labels Nov 14, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2023

@llvm/pr-subscribers-debuginfo
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Michael Buch (Michael137)

Changes

This patch implements the DWARFv5 issue
161118.1: "DW_TAG for C++ static data members".

This will simplify LLDB's handling of static data
members greatly in the long term since we no longer need to differentiate non-static from static data
member declarations using non-portable heuristics.


Full diff: https://github.com/llvm/llvm-project/pull/72235.diff

3 Files Affected:

  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+6-2)
  • (modified) clang/test/CodeGenCXX/debug-info-static-inline-member.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/debug-info-static-member.cpp (+23-13)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 04ca02cfe858579..f3de91d4a39ebee 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1679,9 +1679,13 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy,
   StringRef VName = Var->getName();
 
   llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD);
+  auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
+                 ? llvm::dwarf::DW_TAG_variable
+                 : llvm::dwarf::DW_TAG_member;
   auto Align = getDeclAlignIfRequired(Var, CGM.getContext());
-  llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
-      RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align);
+  llvm::DIDerivedType *GV =
+      DBuilder.createStaticMemberType(RecordTy, VName, VUnit, LineNumber, VTy,
+                                      Flags, /* Val */ nullptr, Tag, Align);
   StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV);
   StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl());
   return GV;
diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
index bfb7ad6b80fabf3..f2d4d9408a8297a 100644
--- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
+++ b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
@@ -1,5 +1,5 @@
-// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
-// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
 
 enum class Enum : int {
   VAL = -1
diff --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp
index 578995801c6400b..a2d25e98ed1cb62 100644
--- a/clang/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp
@@ -1,7 +1,8 @@
-// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s
-// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s
-// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s
-// RUN: %clangxx -target x86_64-windows-msvc -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,NOT-MS %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,NOT-MS %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,NOT-MS %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-5 -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF5 %s
+// RUN: %clangxx -target x86_64-windows-msvc -g -gdwarf-4 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4 %s
 // PR14471
 
 // CHECK: @{{.*}}a{{.*}} = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]]
@@ -39,17 +40,20 @@ class C
 //
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}})
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct"
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var"
+// DWARF4: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var"
+// DWARF5: !DIDerivedType(tag: DW_TAG_variable, name: "anon_static_decl_var"
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "static_decl_templ<int>"
 // CHECK-NOT:              DIFlagFwdDecl
 // CHECK-SAME:             ){{$}}
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
+// DWARF4: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
+// DWARF5: !DIDerivedType(tag: DW_TAG_variable, name: "static_decl_templ_var"
 
 int C::a = 4;
 // CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]], expr: !DIExpression())
 // CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
 // CHECK-SAME:                                declaration: ![[DECL_B:[0-9]+]])
-// CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
+// DWARF4: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
+// DWARF5: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_variable, name: "b"
 // CHECK-NOT:                                 size:
 // CHECK-NOT:                                 align:
 // CHECK-NOT:                                 offset:
@@ -57,40 +61,46 @@ int C::a = 4;
 //
 // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}})
 //
-// CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
+// DWARF4: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
+// DWARF5: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_variable, name: "a"
 // CHECK-NOT:                                 size:
 // CHECK-NOT:                                 align:
 // CHECK-NOT:                                 offset:
 // CHECK-SAME:                                flags: DIFlagStaticMember)
 //
-// CHECK:    ![[CONST_A_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_a"
+// DWARF4:    ![[CONST_A_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_a"
+// DWARF5:    ![[CONST_A_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_variable, name: "const_a"
 // CHECK-NOT:                           size:
 // CHECK-NOT:                           align:
 // CHECK-NOT:                           offset:
 // CHECK-SAME:                          flags: DIFlagStaticMember
 // CHECK-NOT:                           extraData:
 
-// CHECK:     ![[CONST_B_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_b"
+// DWARF4:     ![[CONST_B_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_b"
+// DWARF5:     ![[CONST_B_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_variable, name: "const_b"
 // CHECK-NOT:                            size:
 // CHECK-NOT:                            align:
 // CHECK-NOT:                            offset:
 // CHECK-SAME:                           flags: DIFlagProtected | DIFlagStaticMember
 // CHECK-NOT:                            extraData:
 
-// CHECK: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "c"
+// DWARF4: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "c"
+// DWARF5: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_variable, name: "c"
 // CHECK-NOT:                                 size:
 // CHECK-NOT:                                 align:
 // CHECK-NOT:                                 offset:
 // CHECK-SAME:                                flags: DIFlagPublic | DIFlagStaticMember)
 //
-// CHECK:     ![[CONST_C_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_c"
+// DWARF4:     ![[CONST_C_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_c"
+// DWARF5:     ![[CONST_C_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_variable, name: "const_c"
 // CHECK-NOT:                            size:
 // CHECK-NOT:                            align:
 // CHECK-NOT:                            offset:
 // CHECK-SAME:                           flags: DIFlagPublic | DIFlagStaticMember
 // CHECK-NOT:                            extraData:
 //
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a"
+// DWARF4: !DIDerivedType(tag: DW_TAG_member, name: "x_a"
+// DWARF5: !DIDerivedType(tag: DW_TAG_variable, name: "x_a"
 // CHECK-SAME:           flags: DIFlagPublic | DIFlagStaticMember)
 
 int C::b = 2;

Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

…AG_variable

This patch implements the DWARFv5 issue
161118.1: "DW_TAG for C++ static data members".

This will simplify LLDB's handling of static data
members greatly in the long term since we no longer
need to differentiate non-static from static data
member declarations using non-portable heuristics.
@Michael137 Michael137 force-pushed the dwarf/tag-variable-static-members/PR/2-clang branch from 216100a to a933f17 Compare November 15, 2023 10:32
@Michael137 Michael137 merged commit faa3a5e into llvm:main Nov 15, 2023
Michael137 added a commit that referenced this pull request Nov 15, 2023
…ata members declarations (#72236)

The accepted DWARFv5 issue 161118.1: "DW_TAG for C++ static data
members" specifies that static data member declaration be described by
DW_TAG_variable. Make sure we recognize such members.

Depends on:
* #72234
* #72235
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
…AG_variable (llvm#72235)

This patch implements the DWARFv5 issue 161118.1: "DW_TAG for C++ static
data members".

This will simplify LLDB's handling of static data members greatly in the
long term since we no longer need to differentiate non-static from
static data member declarations using non-portable heuristics.

Depends on:
* llvm#72234
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
…ata members declarations (llvm#72236)

The accepted DWARFv5 issue 161118.1: "DW_TAG for C++ static data
members" specifies that static data member declaration be described by
DW_TAG_variable. Make sure we recognize such members.

Depends on:
* llvm#72234
* llvm#72235
@dwblaikie
Copy link
Collaborator

Should've mentioned this earlier, but we've been seeing crashes in lldb due to this change (though possibly related to our use of GALA python/gdb interop https://github.com/sivachandra/gala - we haven't isolated the failures from that yet (though we've been using it for years, so it's not the proximal cause, at least)). Might be worth reverting so other people aren't tripping over it too.

but working on some repro/isolated/reduced case/something useful to share

@Michael137
Copy link
Member Author

Michael137 commented Jan 3, 2024

Should've mentioned this earlier, but we've been seeing crashes in lldb due to this change (though possibly related to our use of GALA python/gdb interop https://github.com/sivachandra/gala - we haven't isolated the failures from that yet (though we've been using it for years, so it's not the proximal cause, at least)). Might be worth reverting so other people aren't tripping over it too.

but working on some repro/isolated/reduced case/something useful to share

Something reproducible, or a stack trace would be appreciated! The only way I see this change breaking something is in tools that don't expect DW_TAG_subprograms to have DW_TAG_variable children. Maybe there's something missing on the LLDB side, though I haven't noticed anything myself yet

@dwblaikie
Copy link
Collaborator

Should've mentioned this earlier, but we've been seeing crashes in lldb due to this change (though possibly related to our use of GALA python/gdb interop https://github.com/sivachandra/gala - we haven't isolated the failures from that yet (though we've been using it for years, so it's not the proximal cause, at least)). Might be worth reverting so other people aren't tripping over it too.
but working on some repro/isolated/reduced case/something useful to share

Something reproducible, or a stack trace would be appreciated! The only way I see this change breaking something is in tools that don't expect DW_TAG_subprograms to have DW_TAG_variable children. Maybe there's something missing on the LLDB side, though I haven't noticed anything myself yet

Oh, a stack is easy to provide, sure:

 #0 0x000055d7fe816b58 llvm::sys::RunSignalHandlers() (/usr/bin/lldb+0xc616b58)
 #1 0x000055d7fe819477 (/usr/bin/lldb+0xc619477)
 #2 0x00007f10c547c1c0 __restore_rt (/usr/grte/v5/lib64/libpthread.so.0+0x151c0)
 #3 0x000055d7fb7d0f76 clang::CXXRecordDecl::addedMember(clang::Decl*) (/usr/bin/lldb+0x95d0f76)
 #4 0x000055d7fb7c8cec clang::DeclContext::addHiddenDecl(clang::Decl*) (/usr/bin/lldb+0x95c8cec)
 #5 0x000055d7fb7c8d6e clang::DeclContext::addDecl(clang::Decl*) (/usr/bin/lldb+0x95c8d6e)
 #6 0x000055d7f9a2d190 lldb_private::TypeSystemClang::CreateVariableDeclaration(clang::DeclContext*, lldb_private::OptionalClangModuleID, char const*, clang::QualType) (/usr/
bin/lldb+0x782d190)
 #7 0x000055d7f99b9667 DWARFASTParserClang::GetClangDeclForDIE(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b9667)
 #8 0x000055d7f99b94a7 DWARFASTParserClang::GetClangDeclForDIE(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b94a7)
 #9 0x000055d7f99b9325 DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(lldb_private::CompilerDeclContext) (/usr/bin/lldb+0x77b9325)
#10 0x000055d7f9a41e28 lldb_private::TypeSystemClang::DeclContextFindDeclByName(void*, lldb_private::ConstString, bool) (/usr/bin/lldb+0x7841e28)
#11 0x000055d7f9aa25b1 lldb_private::CompilerDeclContext::FindDeclByName(lldb_private::ConstString, bool) (/usr/bin/lldb+0x78a25b1)
#12 0x000055d7f9a72e83 lldb_private::ClangExpressionDeclMap::LookupLocalVariable(lldb_private::NameSearchContext&, lldb_private::ConstString, lldb_private::SymbolContext&, lldb_private::CompilerDeclContext const&) (/usr/bin/lldb+0x7872e83)
#13 0x000055d7f9a70f77 lldb_private::ClangExpressionDeclMap::FindExternalVisibleDecls(lldb_private::NameSearchContext&, std::__u::shared_ptr<lldb_private::Module>, lldb_private::CompilerDeclContext const&) (/usr/bin/lldb+0x7870f77)
#14 0x000055d7f9a707aa lldb_private::ClangExpressionDeclMap::FindExternalVisibleDecls(lldb_private::NameSearchContext&) (/usr/bin/lldb+0x78707aa)
#15 0x000055d7f9a49cbc lldb_private::ClangASTSource::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName) (/usr/bin/lldb+0x7849cbc)
#16 0x000055d7fb7c9c5e clang::DeclContext::lookup(clang::DeclarationName) const (/usr/bin/lldb+0x95c9c5e)
#17 0x000055d7fb077728 (/usr/bin/lldb+0x8e77728)
#18 0x000055d7fb074400 (/usr/bin/lldb+0x8e74400)
#19 0x000055d7fb0739c0 clang::Sema::CppLookupName(clang::LookupResult&, clang::Scope*) (/usr/bin/lldb+0x8e739c0)
#20 0x000055d7fb077010 clang::Sema::LookupName(clang::LookupResult&, clang::Scope*, bool, bool) (/usr/bin/lldb+0x8e77010)
#21 0x000055d7fa999e06 clang::Sema::BuildCXXNestedNameSpecifier(clang::Scope*, clang::Sema::NestedNameSpecInfo&, bool, clang::CXXScopeSpec&, clang::NamedDecl*, bool, bool*, bool) (/usr/bin/lldb+0x8799e06)
#22 0x000055d7fa99b897 clang::Sema::ActOnCXXNestedNameSpecifier(clang::Scope*, clang::Sema::NestedNameSpecInfo&, bool, clang::CXXScopeSpec&, bool*, bool) (/usr/bin/lldb+0x879b897)
#23 0x000055d7fa579fdd clang::Parser::ParseOptionalCXXScopeSpecifier(clang::CXXScopeSpec&, clang::OpaquePtr<clang::QualType>, bool, bool, bool*, bool, clang::IdentifierInfo**, bool, bool) (/usr/bin/lldb+0x8379fdd)
#24 0x000055d7fa54c5ea clang::Parser::TryAnnotateTypeOrScopeToken(clang::ImplicitTypenameContext) (/usr/bin/lldb+0x834c5ea)
#25 0x000055d7fa5d63df clang::Parser::isCXXDeclarationSpecifier(clang::ImplicitTypenameContext, clang::Parser::TPResult, bool*) (/usr/bin/lldb+0x83d63df)
#26 0x000055d7fa5d5b6b clang::Parser::isCXXSimpleDeclaration(bool) (/usr/bin/lldb+0x83d5b6b)
#27 0x000055d7fa5d5a3b clang::Parser::isCXXDeclarationStatement(bool) (/usr/bin/lldb+0x83d5a3b)
#28 0x000055d7fa5fcd2a clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/usr/bin/lldb+0x83fcd2a)
#29 0x000055d7fa5fc7f8 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/usr/bin/lldb+0x83fc7f8)
#30 0x000055d7fa6076d0 clang::Parser::ParseCompoundStatementBody(bool) (/usr/bin/lldb+0x84076d0)
#31 0x000055d7fa608606 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/usr/bin/lldb+0x8408606)
#32 0x000055d7fa5492c8 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/usr/bin/lldb+0x83492c8)
#33 0x000055d7fa5b87da clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/usr/bin/lldb+0x83b87da)
#34 0x000055d7fa547f12 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/usr/bin/lldb+0x8347f12)
#35 0x000055d7fa547918 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/usr/bin/lldb+0x8347918)
#36 0x000055d7fa546b1a clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/usr/bin/lldb+0x8346b1a)
#37 0x000055d7fa544bd7 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/usr/bin/lldb+0x8344bd7)
#38 0x000055d7fa53fbfe clang::ParseAST(clang::Sema&, bool, bool) (/usr/bin/lldb+0x833fbfe)
#39 0x000055d7f9a83577 lldb_private::ClangExpressionParser::ParseInternal(lldb_private::DiagnosticManager&, clang::CodeCompleteConsumer*, unsigned int, unsigned int) (/usr/bin/lldb+0x7883577)
#40 0x000055d7f9a57b9d lldb_private::ClangUserExpression::TryParse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContextScope*, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) (/usr/bin/lldb+0x7857b9d)
#41 0x000055d7f9a58425 lldb_private::ClangUserExpression::Parse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) (/usr/bin/lldb+0x7858425)
#42 0x000055d7f974b5a6 lldb_private::UserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, llvm::StringRef, llvm::StringRef, std::__u::shared_ptr<lldb_private::ValueObject>&, lldb_private::Status&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, lldb_private::ValueObject*) (/usr/bin/lldb+0x754b5a6)
#43 0x000055d7f9b66121 lldb_private::Target::EvaluateExpression(llvm::StringRef, lldb_private::ExecutionContextScope*, std::__u::shared_ptr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, lldb_private::ValueObject*) (/usr/bin/lldb+0x7966121)
#44 0x000055d7f8e38b3f lldb::SBTarget::EvaluateExpression(char const*, lldb::SBExpressionOptions const&) (/usr/bin/lldb+0x6c38b3f)
#45 0x000055d7f8f51f14 (/usr/bin/lldb+0x6d51f14)
#46 0x000055d7f92e7411 (/usr/bin/lldb+0x70e7411)
#47 0x000055d7f92a1535 _PyObject_Call (/usr/bin/lldb+0x70a1535)
#48 0x000055d7f938161e _PyEval_EvalFrameDefault (/usr/bin/lldb+0x718161e)
#49 0x000055d7f9376710 _PyEval_Vector (/usr/bin/lldb+0x7176710)
#50 0x000055d7f92a0cdd _PyObject_FastCallDictTstate (/usr/bin/lldb+0x70a0cdd)
#51 0x000055d7f92a194d _PyObject_Call_Prepend (/usr/bin/lldb+0x70a194d)
#52 0x000055d7f930b839 (/usr/bin/lldb+0x710b839)
#53 0x000055d7f93012fe (/usr/bin/lldb+0x71012fe)
#54 0x000055d7f92a0eb4 _PyObject_MakeTpCall (/usr/bin/lldb+0x70a0eb4)
#55 0x000055d7f937f7c8 _PyEval_EvalFrameDefault (/usr/bin/lldb+0x717f7c8)
#56 0x000055d7f9376710 _PyEval_Vector (/usr/bin/lldb+0x7176710)
#57 0x000055d7f8ea512c lldb_private::python::PythonCallable::operator()(std::initializer_list<lldb_private::python::PythonObject>) (/usr/bin/lldb+0x6ca512c)
#58 0x000055d7f8eb9329 lldb_private::python::SWIGBridge::LLDBSwigPythonCallTypeScript(char const*, void const*, std::__u::shared_ptr<lldb_private::ValueObject> const&, void**, std::__u::shared_ptr<lldb_private::TypeSummaryOptions> const&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&) (/usr/bin/lldb+0x6cb9329)
#59 0x000055d7f8e9b6f3 lldb_private::ScriptInterpreterPythonImpl::GetScriptedSummary(char const*, std::__u::shared_ptr<lldb_private::ValueObject>, std::__u::shared_ptr<lldb_private::StructuredData::Object>&, lldb_private::TypeSummaryOptions const&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&) (/usr/bin/lldb+0x6c9b6f3)
#60 0x000055d7f972adb7 lldb_private::ScriptSummaryFormat::FormatObject(lldb_private::ValueObject*, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&, lldb_private::TypeSummaryOptions const&) (/usr/bin/lldb+0x752adb7)
#61 0x000055d7f96fa691 lldb_private::ValueObject::GetSummaryAsCString(lldb_private::TypeSummaryImpl*, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&, lldb_private::TypeSummaryOptions const&) (/usr/bin/lldb+0x74fa691)
#62 0x000055d7f96fa560 lldb_private::ValueObject::GetSummaryAsCString(lldb_private::TypeSummaryImpl*, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&, lldb::LanguageType) (/usr/bin/lldb+0x74fa560)
#63 0x000055d7f972e094 lldb_private::ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool&, bool&) (/usr/bin/lldb+0x752e094)
#64 0x000055d7f972d2fb lldb_private::ValueObjectPrinter::PrintValueObject() (/usr/bin/lldb+0x752d2fb)
#65 0x000055d7f97007cc lldb_private::ValueObject::Dump(lldb_private::Stream&, lldb_private::DumpValueObjectOptions const&) (/usr/bin/lldb+0x75007cc)
#66 0x000055d7f9786d2f lldb_private::CommandObjectDWIMPrint::DoExecute(llvm::StringRef, lldb_private::CommandReturnObject&) (/usr/bin/lldb+0x7586d2f)
#67 0x000055d7f984354a lldb_private::CommandObjectRaw::Execute(char const*, lldb_private::CommandReturnObject&) (/usr/bin/lldb+0x764354a)
#68 0x000055d7f975c10b lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, bool) (/usr/bin/lldb+0x755c10b)
#69 0x000055d7f9760cb5 lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&) (/usr/bin/lldb+0x7560cb5)
#70 0x000055d7f96c29a3 lldb_private::IOHandlerEditline::Run() (/usr/bin/lldb+0x74c29a3)
#71 0x000055d7f96a1a96 lldb_private::Debugger::RunIOHandlers() (/usr/bin/lldb+0x74a1a96)
#72 0x000055d7f9762a0a lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&) (/usr/bin/lldb+0x7562a0a)
#73 0x000055d7f8da176c lldb::SBDebugger::RunCommandInterpreter(lldb::SBCommandInterpreterRunOptions const&) (/usr/bin/lldb+0x6ba176c)
#74 0x000055d7f8d819f5 Driver::MainLoop() (/usr/bin/lldb+0x6b819f5)
#75 0x000055d7f8d829a1 main (/usr/bin/lldb+0x6b829a1)
#76 0x00007f10c52d0633 __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x61633)
#77 0x000055d7f8d7e02a _start (/usr/bin/lldb+0x6b7e02a)

@dwblaikie
Copy link
Collaborator

Perhaps not surprisingly from the backtrace, the DIE that's tripping things up is the DW_TAG_variable here:

0x00003819:   DW_TAG_class_type
                DW_AT_name      ("ScopedLockService")
                DW_AT_declaration       (true)

0x0000381b:     DW_TAG_variable
                  DW_AT_name    ("close_callback")
                  DW_AT_type    (0x00003825 "Callback1<LockService *> *")
                  DW_AT_decl_file       (0x04)
                  DW_AT_decl_line       (531)
                  DW_AT_external        (true)
                  DW_AT_declaration     (true)

(so a case where ctor homing/-fno-standalone-debug has kept the type definition elsewhere, but the DW_TAG_variable is emitted here)

Might help me reproduce this in a standalone example..

@dwblaikie
Copy link
Collaborator

Yeah, that seems to do it:

struct t1 {
  t1();
  static int i;
};
int t1::i = 43;
int main() {
}
$ clang++-tot -gsplit-dwarf -g test.cpp
$ lldb ./a.out -o "b main" -o "run" -o "p t1::i" -batch
This is google-lldb.
Help: http://go/lldb. File a bug: http://go/lldb-bug.
Stop hook #1 added.
(lldb) target create "./a.out"
Current executable set to '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64).
(lldb) b main
Breakpoint 1: where = a.out`main + 4 at test.cpp:7:1, address = 0x0000000000001134
(lldb) run
Process 2043063 launched: '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64)
Process 2043063 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x0000555555555134 a.out`main at test.cpp:7:1
   4    };
   5    int t1::i = 43;
   6    int main() {
-> 7    }
(lldb) p t1::i
PLEASE submit a bug report to http://go/llvm-crash-bug and include the crash backtrace.
Stack dump:
0.      Program arguments: lldb ./a.out -o "b main" -o run -o "p t1::i" -batch
1.      HandleCommand(command = "p t1::i")
2.      <user expression 0>:1:5: current parser token 'i'
3.      <lldb wrapper prefix>:44:1: parsing function body '$__lldb_expr'
4.      <lldb wrapper prefix>:44:1: in compound statement ('{}')
 #0 0x00005557cda16b58 llvm::sys::RunSignalHandlers() (/usr/bin/lldb+0xc616b58)
 #1 0x00005557cda19477 (/usr/bin/lldb+0xc619477)
 #2 0x00007fb4905861c0 __restore_rt (/usr/grte/v5/lib64/libpthread.so.0+0x151c0)
 #3 0x00005557ca9d0f76 clang::CXXRecordDecl::addedMember(clang::Decl*) (/usr/bin/lldb+0x95d0f76)
 #4 0x00005557ca9c8cec clang::DeclContext::addHiddenDecl(clang::Decl*) (/usr/bin/lldb+0x95c8cec)
 #5 0x00005557ca9c8d6e clang::DeclContext::addDecl(clang::Decl*) (/usr/bin/lldb+0x95c8d6e)
 #6 0x00005557c8c2d190 lldb_private::TypeSystemClang::CreateVariableDeclaration(clang::DeclContext*, lldb_private::OptionalClangModuleID, char const*, clang::QualType) (/usr/bin/lldb+0x782d190)
 #7 0x00005557c8bb9667 DWARFASTParserClang::GetClangDeclForDIE(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b9667)
 #8 0x00005557c8bb94a7 DWARFASTParserClang::GetClangDeclForDIE(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b94a7)
 #9 0x00005557c8bb976e DWARFASTParserClang::GetDeclForUIDFromDWARF(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b976e)
#10 0x00005557c8b88fac lldb_private::plugin::dwarf::SymbolFileDWARF::GetDeclForUID(unsigned long) (/usr/bin/lldb+0x7788fac)
#11 0x00005557c8ceaf2d lldb_private::Variable::GetDecl() (/usr/bin/lldb+0x78eaf2d)
#12 0x00005557c8c72e26 lldb_private::ClangExpressionDeclMap::LookupLocalVariable(lldb_private::NameSearchContext&, lldb_private::ConstString, lldb_private::SymbolContext&, lldb_private::CompilerDeclContext const&) (/usr/bin/lldb+0x7872e26)
#13 0x00005557c8c70f77 lldb_private::ClangExpressionDeclMap::FindExternalVisibleDecls(lldb_private::NameSearchContext&, std::__u::shared_ptr<lldb_private::Module>, lldb_private::CompilerDeclContext const&) (/usr/bin/lldb+0x7870f77)
#14 0x00005557c8c707aa lldb_private::ClangExpressionDeclMap::FindExternalVisibleDecls(lldb_private::NameSearchContext&) (/usr/bin/lldb+0x78707aa)
#15 0x00005557c8c49cbc lldb_private::ClangASTSource::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName) (/usr/bin/lldb+0x7849cbc)
#16 0x00005557ca9c9c5e clang::DeclContext::lookup(clang::DeclarationName) const (/usr/bin/lldb+0x95c9c5e)
#17 0x00005557ca277728 (/usr/bin/lldb+0x8e77728)
#18 0x00005557ca274400 (/usr/bin/lldb+0x8e74400)
#19 0x00005557ca2739c0 clang::Sema::CppLookupName(clang::LookupResult&, clang::Scope*) (/usr/bin/lldb+0x8e739c0)
#20 0x00005557ca277010 clang::Sema::LookupName(clang::LookupResult&, clang::Scope*, bool, bool) (/usr/bin/lldb+0x8e77010)
#21 0x00005557c9b99e06 clang::Sema::BuildCXXNestedNameSpecifier(clang::Scope*, clang::Sema::NestedNameSpecInfo&, bool, clang::CXXScopeSpec&, clang::NamedDecl*, bool, bool*, bool) (/usr/bin/lldb+0x8799e06)
#22 0x00005557c9b9b897 clang::Sema::ActOnCXXNestedNameSpecifier(clang::Scope*, clang::Sema::NestedNameSpecInfo&, bool, clang::CXXScopeSpec&, bool*, bool) (/usr/bin/lldb+0x879b897)
#23 0x00005557c9779fdd clang::Parser::ParseOptionalCXXScopeSpecifier(clang::CXXScopeSpec&, clang::OpaquePtr<clang::QualType>, bool, bool, bool*, bool, clang::IdentifierInfo**, bool, bool) (/usr/bin/lldb+0x8379fdd)
#24 0x00005557c974c5ea clang::Parser::TryAnnotateTypeOrScopeToken(clang::ImplicitTypenameContext) (/usr/bin/lldb+0x834c5ea)
#25 0x00005557c97d63df clang::Parser::isCXXDeclarationSpecifier(clang::ImplicitTypenameContext, clang::Parser::TPResult, bool*) (/usr/bin/lldb+0x83d63df)
#26 0x00005557c97d5b6b clang::Parser::isCXXSimpleDeclaration(bool) (/usr/bin/lldb+0x83d5b6b)
#27 0x00005557c97d5a3b clang::Parser::isCXXDeclarationStatement(bool) (/usr/bin/lldb+0x83d5a3b)
#28 0x00005557c97fcd2a clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/usr/bin/lldb+0x83fcd2a)
#29 0x00005557c97fc7f8 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/usr/bin/lldb+0x83fc7f8)
#30 0x00005557c98076d0 clang::Parser::ParseCompoundStatementBody(bool) (/usr/bin/lldb+0x84076d0)
#31 0x00005557c9808606 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/usr/bin/lldb+0x8408606)
#32 0x00005557c97492c8 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/usr/bin/lldb+0x83492c8)
#33 0x00005557c97b87da clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/usr/bin/lldb+0x83b87da)
#34 0x00005557c9747f12 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/usr/bin/lldb+0x8347f12)
#35 0x00005557c9747918 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/usr/bin/lldb+0x8347918)
#36 0x00005557c9746b1a clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/usr/bin/lldb+0x8346b1a)
#37 0x00005557c9744bd7 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/usr/bin/lldb+0x8344bd7)
#38 0x00005557c973fbfe clang::ParseAST(clang::Sema&, bool, bool) (/usr/bin/lldb+0x833fbfe)
#39 0x00005557c8c83577 lldb_private::ClangExpressionParser::ParseInternal(lldb_private::DiagnosticManager&, clang::CodeCompleteConsumer*, unsigned int, unsigned int) (/usr/bin/lldb+0x7883577)
#40 0x00005557c8c57b9d lldb_private::ClangUserExpression::TryParse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContextScope*, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) (/usr/bin/lldb+0x7857b9d)
#41 0x00005557c8c58425 lldb_private::ClangUserExpression::Parse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) (/usr/bin/lldb+0x7858425)
#42 0x00005557c894b5a6 lldb_private::UserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, llvm::StringRef, llvm::StringRef, std::__u::shared_ptr<lldb_private::ValueObject>&, lldb_private::Status&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, lldb_private::ValueObject*) (/usr/bin/lldb+0x754b5a6)
#43 0x00005557c8d66121 lldb_private::Target::EvaluateExpression(llvm::StringRef, lldb_private::ExecutionContextScope*, std::__u::shared_ptr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, lldb_private::ValueObject*) (/usr/bin/lldb+0x7966121)
#44 0x00005557c8986beb lldb_private::CommandObjectDWIMPrint::DoExecute(llvm::StringRef, lldb_private::CommandReturnObject&) (/usr/bin/lldb+0x7586beb)
#45 0x00005557c8a4354a lldb_private::CommandObjectRaw::Execute(char const*, lldb_private::CommandReturnObject&) (/usr/bin/lldb+0x764354a)
#46 0x00005557c895c10b lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, bool) (/usr/bin/lldb+0x755c10b)
#47 0x00005557c8960cb5 lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&) (/usr/bin/lldb+0x7560cb5)
#48 0x00005557c88c29a3 lldb_private::IOHandlerEditline::Run() (/usr/bin/lldb+0x74c29a3)
#49 0x00005557c88a1a96 lldb_private::Debugger::RunIOHandlers() (/usr/bin/lldb+0x74a1a96)
#50 0x00005557c8962a0a lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&) (/usr/bin/lldb+0x7562a0a)
#51 0x00005557c7fa176c lldb::SBDebugger::RunCommandInterpreter(lldb::SBCommandInterpreterRunOptions const&) (/usr/bin/lldb+0x6ba176c)
#52 0x00005557c7f819f5 Driver::MainLoop() (/usr/bin/lldb+0x6b819f5)
#53 0x00005557c7f829a1 main (/usr/bin/lldb+0x6b829a1)
#54 0x00007fb4903da633 __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x61633)
#55 0x00005557c7f7e02a _start (/usr/bin/lldb+0x6b7e02a)
LLDB diagnostics will be written to /tmp/diagnostics-6518ff
Please include the directory content when filing a bug report
Segmentation fault

(Hmm, maybe our google build of lldb enables something to print the stack trace - I can reproduce this with (in this case with a debug+asserts build) an open source build of lldb too, like this:)

$ LD_LIBRARY_PATH=$HOME/dev/llvm/build/default/lib ~/dev/llvm/build/default/bin/lldb ./a.out -o "b main" -o "run" -o "p t1::i" 
-batch 
(lldb) target create "./a.out"
Current executable set to '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64).
(lldb) b main
Breakpoint 1: where = a.out`main + 4 at test.cpp:7:1, address = 0x0000000000001134
(lldb) run
Process 2047004 launched: '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64)
Process 2047004 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x0000555555555134 a.out`main at test.cpp:7:1
   4    };
   5    int t1::i = 43;
   6    int main() {
-> 7    }
(lldb) p t1::i
lldb: /usr/local/google/home/blaikie/dev/llvm/src/llvm/../clang/include/clang/AST/DeclCXX.h:464: struct DefinitionData &clang::CXXRecordDecl::data() const: Assertion `DD && "queried property of class with no definition"' failed.
LLDB diagnostics will be written to /tmp/diagnostics-12c7ac
Please include the directory content when filing a bug report
Aborted

@Michael137
Copy link
Member Author

Yeah, that seems to do it:


struct t1 {

  t1();

  static int i;

};

int t1::i = 43;

int main() {

}


$ clang++-tot -gsplit-dwarf -g test.cpp

$ lldb ./a.out -o "b main" -o "run" -o "p t1::i" -batch

This is google-lldb.

Help: http://go/lldb. File a bug: http://go/lldb-bug.

Stop hook #1 added.

(lldb) target create "./a.out"

Current executable set to '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64).

(lldb) b main

Breakpoint 1: where = a.out`main + 4 at test.cpp:7:1, address = 0x0000000000001134

(lldb) run

Process 2043063 launched: '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64)

Process 2043063 stopped

* thread #1, name = 'a.out', stop reason = breakpoint 1.1

    frame #0: 0x0000555555555134 a.out`main at test.cpp:7:1

   4    };

   5    int t1::i = 43;

   6    int main() {

-> 7    }

(lldb) p t1::i

PLEASE submit a bug report to http://go/llvm-crash-bug and include the crash backtrace.

Stack dump:

0.      Program arguments: lldb ./a.out -o "b main" -o run -o "p t1::i" -batch

1.      HandleCommand(command = "p t1::i")

2.      <user expression 0>:1:5: current parser token 'i'

3.      <lldb wrapper prefix>:44:1: parsing function body '$__lldb_expr'

4.      <lldb wrapper prefix>:44:1: in compound statement ('{}')

 #0 0x00005557cda16b58 llvm::sys::RunSignalHandlers() (/usr/bin/lldb+0xc616b58)

 #1 0x00005557cda19477 (/usr/bin/lldb+0xc619477)

 #2 0x00007fb4905861c0 __restore_rt (/usr/grte/v5/lib64/libpthread.so.0+0x151c0)

 #3 0x00005557ca9d0f76 clang::CXXRecordDecl::addedMember(clang::Decl*) (/usr/bin/lldb+0x95d0f76)

 #4 0x00005557ca9c8cec clang::DeclContext::addHiddenDecl(clang::Decl*) (/usr/bin/lldb+0x95c8cec)

 #5 0x00005557ca9c8d6e clang::DeclContext::addDecl(clang::Decl*) (/usr/bin/lldb+0x95c8d6e)

 #6 0x00005557c8c2d190 lldb_private::TypeSystemClang::CreateVariableDeclaration(clang::DeclContext*, lldb_private::OptionalClangModuleID, char const*, clang::QualType) (/usr/bin/lldb+0x782d190)

 #7 0x00005557c8bb9667 DWARFASTParserClang::GetClangDeclForDIE(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b9667)

 #8 0x00005557c8bb94a7 DWARFASTParserClang::GetClangDeclForDIE(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b94a7)

 #9 0x00005557c8bb976e DWARFASTParserClang::GetDeclForUIDFromDWARF(lldb_private::plugin::dwarf::DWARFDIE const&) (/usr/bin/lldb+0x77b976e)

#10 0x00005557c8b88fac lldb_private::plugin::dwarf::SymbolFileDWARF::GetDeclForUID(unsigned long) (/usr/bin/lldb+0x7788fac)

#11 0x00005557c8ceaf2d lldb_private::Variable::GetDecl() (/usr/bin/lldb+0x78eaf2d)

#12 0x00005557c8c72e26 lldb_private::ClangExpressionDeclMap::LookupLocalVariable(lldb_private::NameSearchContext&, lldb_private::ConstString, lldb_private::SymbolContext&, lldb_private::CompilerDeclContext const&) (/usr/bin/lldb+0x7872e26)

#13 0x00005557c8c70f77 lldb_private::ClangExpressionDeclMap::FindExternalVisibleDecls(lldb_private::NameSearchContext&, std::__u::shared_ptr<lldb_private::Module>, lldb_private::CompilerDeclContext const&) (/usr/bin/lldb+0x7870f77)

#14 0x00005557c8c707aa lldb_private::ClangExpressionDeclMap::FindExternalVisibleDecls(lldb_private::NameSearchContext&) (/usr/bin/lldb+0x78707aa)

#15 0x00005557c8c49cbc lldb_private::ClangASTSource::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName) (/usr/bin/lldb+0x7849cbc)

#16 0x00005557ca9c9c5e clang::DeclContext::lookup(clang::DeclarationName) const (/usr/bin/lldb+0x95c9c5e)

#17 0x00005557ca277728 (/usr/bin/lldb+0x8e77728)

#18 0x00005557ca274400 (/usr/bin/lldb+0x8e74400)

#19 0x00005557ca2739c0 clang::Sema::CppLookupName(clang::LookupResult&, clang::Scope*) (/usr/bin/lldb+0x8e739c0)

#20 0x00005557ca277010 clang::Sema::LookupName(clang::LookupResult&, clang::Scope*, bool, bool) (/usr/bin/lldb+0x8e77010)

#21 0x00005557c9b99e06 clang::Sema::BuildCXXNestedNameSpecifier(clang::Scope*, clang::Sema::NestedNameSpecInfo&, bool, clang::CXXScopeSpec&, clang::NamedDecl*, bool, bool*, bool) (/usr/bin/lldb+0x8799e06)

#22 0x00005557c9b9b897 clang::Sema::ActOnCXXNestedNameSpecifier(clang::Scope*, clang::Sema::NestedNameSpecInfo&, bool, clang::CXXScopeSpec&, bool*, bool) (/usr/bin/lldb+0x879b897)

#23 0x00005557c9779fdd clang::Parser::ParseOptionalCXXScopeSpecifier(clang::CXXScopeSpec&, clang::OpaquePtr<clang::QualType>, bool, bool, bool*, bool, clang::IdentifierInfo**, bool, bool) (/usr/bin/lldb+0x8379fdd)

#24 0x00005557c974c5ea clang::Parser::TryAnnotateTypeOrScopeToken(clang::ImplicitTypenameContext) (/usr/bin/lldb+0x834c5ea)

#25 0x00005557c97d63df clang::Parser::isCXXDeclarationSpecifier(clang::ImplicitTypenameContext, clang::Parser::TPResult, bool*) (/usr/bin/lldb+0x83d63df)

#26 0x00005557c97d5b6b clang::Parser::isCXXSimpleDeclaration(bool) (/usr/bin/lldb+0x83d5b6b)

#27 0x00005557c97d5a3b clang::Parser::isCXXDeclarationStatement(bool) (/usr/bin/lldb+0x83d5a3b)

#28 0x00005557c97fcd2a clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/usr/bin/lldb+0x83fcd2a)

#29 0x00005557c97fc7f8 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/usr/bin/lldb+0x83fc7f8)

#30 0x00005557c98076d0 clang::Parser::ParseCompoundStatementBody(bool) (/usr/bin/lldb+0x84076d0)

#31 0x00005557c9808606 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/usr/bin/lldb+0x8408606)

#32 0x00005557c97492c8 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/usr/bin/lldb+0x83492c8)

#33 0x00005557c97b87da clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/usr/bin/lldb+0x83b87da)

#34 0x00005557c9747f12 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/usr/bin/lldb+0x8347f12)

#35 0x00005557c9747918 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/usr/bin/lldb+0x8347918)

#36 0x00005557c9746b1a clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/usr/bin/lldb+0x8346b1a)

#37 0x00005557c9744bd7 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/usr/bin/lldb+0x8344bd7)

#38 0x00005557c973fbfe clang::ParseAST(clang::Sema&, bool, bool) (/usr/bin/lldb+0x833fbfe)

#39 0x00005557c8c83577 lldb_private::ClangExpressionParser::ParseInternal(lldb_private::DiagnosticManager&, clang::CodeCompleteConsumer*, unsigned int, unsigned int) (/usr/bin/lldb+0x7883577)

#40 0x00005557c8c57b9d lldb_private::ClangUserExpression::TryParse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContextScope*, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) (/usr/bin/lldb+0x7857b9d)

#41 0x00005557c8c58425 lldb_private::ClangUserExpression::Parse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) (/usr/bin/lldb+0x7858425)

#42 0x00005557c894b5a6 lldb_private::UserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, llvm::StringRef, llvm::StringRef, std::__u::shared_ptr<lldb_private::ValueObject>&, lldb_private::Status&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, lldb_private::ValueObject*) (/usr/bin/lldb+0x754b5a6)

#43 0x00005557c8d66121 lldb_private::Target::EvaluateExpression(llvm::StringRef, lldb_private::ExecutionContextScope*, std::__u::shared_ptr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, lldb_private::ValueObject*) (/usr/bin/lldb+0x7966121)

#44 0x00005557c8986beb lldb_private::CommandObjectDWIMPrint::DoExecute(llvm::StringRef, lldb_private::CommandReturnObject&) (/usr/bin/lldb+0x7586beb)

#45 0x00005557c8a4354a lldb_private::CommandObjectRaw::Execute(char const*, lldb_private::CommandReturnObject&) (/usr/bin/lldb+0x764354a)

#46 0x00005557c895c10b lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, bool) (/usr/bin/lldb+0x755c10b)

#47 0x00005557c8960cb5 lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>&) (/usr/bin/lldb+0x7560cb5)

#48 0x00005557c88c29a3 lldb_private::IOHandlerEditline::Run() (/usr/bin/lldb+0x74c29a3)

#49 0x00005557c88a1a96 lldb_private::Debugger::RunIOHandlers() (/usr/bin/lldb+0x74a1a96)

#50 0x00005557c8962a0a lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&) (/usr/bin/lldb+0x7562a0a)

#51 0x00005557c7fa176c lldb::SBDebugger::RunCommandInterpreter(lldb::SBCommandInterpreterRunOptions const&) (/usr/bin/lldb+0x6ba176c)

#52 0x00005557c7f819f5 Driver::MainLoop() (/usr/bin/lldb+0x6b819f5)

#53 0x00005557c7f829a1 main (/usr/bin/lldb+0x6b829a1)

#54 0x00007fb4903da633 __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x61633)

#55 0x00005557c7f7e02a _start (/usr/bin/lldb+0x6b7e02a)

LLDB diagnostics will be written to /tmp/diagnostics-6518ff

Please include the directory content when filing a bug report

Segmentation fault

(Hmm, maybe our google build of lldb enables something to print the stack trace - I can reproduce this with (in this case with a debug+asserts build) an open source build of lldb too, like this:)


$ LD_LIBRARY_PATH=$HOME/dev/llvm/build/default/lib ~/dev/llvm/build/default/bin/lldb ./a.out -o "b main" -o "run" -o "p t1::i" 

-batch 

(lldb) target create "./a.out"

Current executable set to '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64).

(lldb) b main

Breakpoint 1: where = a.out`main + 4 at test.cpp:7:1, address = 0x0000000000001134

(lldb) run

Process 2047004 launched: '/usr/local/google/home/blaikie/dev/scratch/a.out' (x86_64)

Process 2047004 stopped

* thread #1, name = 'a.out', stop reason = breakpoint 1.1

    frame #0: 0x0000555555555134 a.out`main at test.cpp:7:1

   4    };

   5    int t1::i = 43;

   6    int main() {

-> 7    }

(lldb) p t1::i

lldb: /usr/local/google/home/blaikie/dev/llvm/src/llvm/../clang/include/clang/AST/DeclCXX.h:464: struct DefinitionData &clang::CXXRecordDecl::data() const: Assertion `DD && "queried property of class with no definition"' failed.

LLDB diagnostics will be written to /tmp/diagnostics-12c7ac

Please include the directory content when filing a bug report

Aborted

Awesome thanks for the reproducer! Will look into it asap

@dwblaikie
Copy link
Collaborator

In our practical example this clearly reproduces in cases where the definition is available in another .dwo within the same executable. So I'm guessing something needs to go looking for a definition (& then if it can't find one, fail gracefully) here. There's probably some abstraction in lldb for doing that "oh, we need a type definition here, try to find one".

@Michael137
Copy link
Member Author

Michael137 commented Jan 4, 2024

Ah looks like in GetClangDeclForDIE, when trying to parse the DW_AT_specification that the CU-level DW_TAG_variable points to, we now try to CreateVariableDeclaration, because the static member is a DW_TAG_variable too. Whereas previously we would just fall-through this switch-statement, i.e., it was a no-op. Adding VarDecls to RecordDecls for static data members should always be done in CreateStaticMemberVariable.

Maybe the solution is to add a check inside GetClangDeclForDIE whether we're referring to a static data member, and if we do, restore previous behaviour where we don't try to create a VarDecl at that point.

In your reproducer it looks like we only ever emit a forward declaration for the containing structure t1. So it seems like for DWARFv4, we just never end up trying to call CreateStaticMemberVariable on a CXXRecordDecl without a definition. I don't think there's a good way to work around the lack of a definition for t1, i.e., expression evaluation would never work for this use-case (even with DWARFv4). We'll need a more elaborate test-case where the definition for t1 is in a different .dwo, as you say. Hopefully the fix I suggested would make expression evaluation still work (since it should really just restore DWARFv4 code-paths).

@dwblaikie
Copy link
Collaborator

Yes, in the totally reduced reproducer - another debugger might be able to do this name lookup with only a declaration, but I understand that at least Clang's AST expression evaluator wouldn't be able to handle this case. (though perhaps the lldb-eval work will provide some opportunity to catch this case)

But at least in our real-world example I think the definition is available, in another DWO in the same executable. But I don't have a small reproducer for that - small examples "just work" (they do find the type definition, don't crash) - but in the larger one we still see the crash depending on exactly where the expression is evaluated (within a fully statically linked binary - so the definition is available, broadly speaking, no matter the context of evaluation - not sure what makes the difference)

If it's helpful to try to identify the more nuanced case where a crash occurs despite the definition being available /somewhere/, I can try to figure that out but it seems difficult to do so.

@Michael137
Copy link
Member Author

Michael137 commented Jan 5, 2024

Yes, in the totally reduced reproducer - another debugger might be able to do this name lookup with only a declaration, but I understand that at least Clang's AST expression evaluator wouldn't be able to handle this case. (though perhaps the lldb-eval work will provide some opportunity to catch this case)

But at least in our real-world example I think the definition is available, in another DWO in the same executable. But I don't have a small reproducer for that - small examples "just work" (they do find the type definition, don't crash) - but in the larger one we still see the crash depending on exactly where the expression is evaluated (within a fully statically linked binary - so the definition is available, broadly speaking, no matter the context of evaluation - not sure what makes the difference)

If it's helpful to try to identify the more nuanced case where a crash occurs despite the definition being available /somewhere/, I can try to figure that out but it seems difficult to do so.

I'll submit a PR later today to get us back to previous behaviour. The test will just use your minimal reproducer to make sure we don't crash

@dwblaikie
Copy link
Collaborator

Thanks!

@Michael137
Copy link
Member Author

Proposed fix: #77155

@Michael137
Copy link
Member Author

@dwblaikie merged the fix, let me know if you're still seeing problems

@dwblaikie
Copy link
Collaborator

looking good from what I've tested - thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants