[Lldb-commits] [lldb] 15f9020 - [lldb/DWARF] Respect member layout for types parsed through declarations (#110648)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 2 02:13:47 PDT 2024
Author: Pavel Labath
Date: 2024-10-02T11:13:43+02:00
New Revision: 15f90203bcbc685e8d63a7e52e60adff02bf5499
URL: https://github.com/llvm/llvm-project/commit/15f90203bcbc685e8d63a7e52e60adff02bf5499
DIFF: https://github.com/llvm/llvm-project/commit/15f90203bcbc685e8d63a7e52e60adff02bf5499.diff
LOG: [lldb/DWARF] Respect member layout for types parsed through declarations (#110648)
LLDB code for using the type layout data from DWARF was not kicking in
for types which were initially parsed from a declaration. The problem
was in these lines of code:
```
if (type)
layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8;
```
which determine the types layout size by getting the size from the
lldb_private::Type object. The problem is that if the type object does
not have this information cached, this request can trigger another
(recursive) request to lay out/complete the type. This one, somewhat
surprisingly, succeeds, but does that without the type layout
information (because it hasn't been computed yet). The reasons why this
hasn't been noticed so far are:
- this is a relatively new bug. I haven't checked but I suspect it was
introduced in the "delay type definition search" patchset from this
summer -- if we search for the definition eagerly, we will always have a
cached size value.
- it requires the presence of another bug/issue, as otherwise the
automatically computed layout will match the real thing.
- it reproduces (much) more easily with -flimit-debug-info (though it is
possible to trigger it without that flag).
My fix consists of always fetching type size information from DWARF
(which so far existed as a fallback path). I'm not quite sure why this
code was there in the first place (the code goes back to before the
Great LLDB Reformat), but I don't believe it is necessary, as the type
size (for types parsed from definition DIEs) is set exactly from this
attribute (in ParseStructureLikeDIE).
Added:
lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 70540fe7fada68..a30d898a93cc4d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2128,14 +2128,10 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
TypeSystemClang::BuildIndirectFields(clang_type);
TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
- if (type)
- layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8;
- if (layout_info.bit_size == 0)
- layout_info.bit_size =
- die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
- if (layout_info.alignment == 0)
- layout_info.alignment =
- die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;
+ layout_info.bit_size =
+ die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+ layout_info.alignment =
+ die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;
clang::CXXRecordDecl *record_decl =
m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s
new file mode 100644
index 00000000000000..27715c5004720a
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s
@@ -0,0 +1,132 @@
+## Test that lldb respects the layout defined in DWARF even when starting out
+## with a declaration of the class.
+
+# RUN: split-file %s %t
+# RUN: llvm-mc --triple x86_64-pc-linux %t/asm --filetype=obj -o %t.o
+# RUN: %lldb -s %t/commands -o exit %t.o 2>&1 | FileCheck %s
+
+#--- commands
+target var a -fx
+# CHECK-LABEL: target var a
+# CHECK: (A) a = (i = 0xbaadf00d)
+
+#--- asm
+ .data
+ .p2align 4
+ .long 0
+a:
+ .long 0xdeadbeef
+ .long 0xbaadf00d
+
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 8 # DW_FORM_string
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] DW_TAG_compile_unit
+ .asciz "Hand-written DWARF" # DW_AT_producer
+
+ .byte 2 # Abbrev [2] DW_TAG_variable
+ .asciz "a" # DW_AT_name
+ .long .LA_decl-.Lcu_begin0 # DW_AT_type
+ .byte 9 # DW_AT_location
+ .byte 3
+ .quad a
+.LA_decl:
+ .byte 3 # Abbrev [3] DW_TAG_structure_type
+ .asciz "A" # DW_AT_name
+ # DW_AT_declaration
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+
+.Lcu_begin1:
+ .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] DW_TAG_compile_unit
+ .asciz "Hand-written DWARF" # DW_AT_producer
+
+ .byte 4 # Abbrev [4] DW_TAG_structure_type
+ .asciz "A" # DW_AT_name
+ # DW_AT_declaration
+ .byte 8 # DW_AT_byte_size
+ .byte 5 # Abbrev [5] DW_TAG_member
+ .asciz "i" # DW_AT_name
+ .long .Lint-.Lcu_begin1 # DW_AT_type
+## NB: empty padding before this member
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+
+.Lint:
+ .byte 6 # Abbrev [6] DW_TAG_base_type
+ .asciz "int" # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end1:
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
index 8633d02f492e67..16bdbd3cfaad6e 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
@@ -105,6 +105,8 @@ c1:
.byte 1 # DW_CHILDREN_yes
.byte 3 # DW_AT_name
.byte 8 # DW_FORM_string
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 7 # Abbreviation Code
@@ -251,6 +253,7 @@ c1:
.LB1:
.byte 6 # Abbrev [6] DW_TAG_class_type
.asciz "B1" # DW_AT_name
+ .byte 8 # DW_AT_byte_size
.byte 7 # Abbrev [5] 0x58:0xc DW_TAG_member
.asciz "ptr" # DW_AT_name
.long .LAptr # DW_AT_type
More information about the lldb-commits
mailing list