[Lldb-commits] [lldb] DRAFT: [lldb][DWARFASTParserClang] Remove old workaround (PR #160132)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 29 07:39:26 PDT 2025


https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/160132

>From 23a1d704e477ae05e5504004835b8cf766092c39 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 22 Sep 2025 16:02:35 +0100
Subject: [PATCH] [lldb][DWARFASTParserClang] Simplify obsolete error condition
 for malformed array member type offsets

This code was introduced in `fa3ab4599d717feedbb83e08e7f654913942520b` to work around a debug-info generation bug in Clang. This bug was fixed in Clang-4. The check has since been adjusted (first in `808ff186f6a6ba1fd38cc7e00697cd82f4afe540`, and then most recently in `370db9c62910195e664e82dde6f0adb3e255a4fd`).

This codepath is getting quite convoluted, and all it does is turn an `array[1]` into an `array[0]` type when it is deemed correct (which is only true in corrupted DWARF from around 2012). At this point the workaround probably never fires, apart from actually valid codegen. This patch removes this workaround.

Added some shell tests for malformed DWARF just to check that LLDB at the very least doesn't crash.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  37 ------
 ...ncomplete-member-beyond-parent-bounds.yaml | 104 +++++++++++++++++
 .../DWARF/member-beyond-parent-bounds.yaml    | 109 ++++++++++++++++++
 .../DWARF/member-on-parent-bounds.yaml        | 109 ++++++++++++++++++
 .../DWARF/union-types-no-member-location.yaml |   4 -
 .../zero-sized-member-in-parent-bounds.yaml   | 105 +++++++++++++++++
 6 files changed, 427 insertions(+), 41 deletions(-)
 create mode 100644 lldb/test/Shell/SymbolFile/DWARF/incomplete-member-beyond-parent-bounds.yaml
 create mode 100644 lldb/test/Shell/SymbolFile/DWARF/member-beyond-parent-bounds.yaml
 create mode 100644 lldb/test/Shell/SymbolFile/DWARF/member-on-parent-bounds.yaml
 create mode 100644 lldb/test/Shell/SymbolFile/DWARF/zero-sized-member-in-parent-bounds.yaml

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index f1e73d73a733b..82e9d867c3ac0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -3126,43 +3126,6 @@ void DWARFASTParserClang::ParseSingleMember(
   if (!member_clang_type.IsCompleteType())
     member_clang_type.GetCompleteType();
 
-  {
-    // Older versions of clang emit the same DWARF for array[0] and array[1]. If
-    // the current field is at the end of the structure, then there is
-    // definitely no room for extra elements and we override the type to
-    // array[0]. This was fixed by f454dfb6b5af.
-    CompilerType member_array_element_type;
-    uint64_t member_array_size;
-    bool member_array_is_incomplete;
-
-    if (member_clang_type.IsArrayType(&member_array_element_type,
-                                      &member_array_size,
-                                      &member_array_is_incomplete) &&
-        !member_array_is_incomplete) {
-      uint64_t parent_byte_size =
-          parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
-
-      // If the attrs.member_byte_offset is still set to UINT32_MAX this means
-      // that the DW_TAG_member didn't have a DW_AT_data_member_location, so
-      // don't emit an error if this is the case.
-      if (attrs.member_byte_offset != UINT32_MAX &&
-          attrs.member_byte_offset >= parent_byte_size) {
-        if (member_array_size != 1 &&
-            (member_array_size != 0 ||
-             attrs.member_byte_offset > parent_byte_size)) {
-          module_sp->ReportError(
-              "{0:x8}: DW_TAG_member '{1}' refers to type {2:x16}"
-              " which extends beyond the bounds of {3:x8}",
-              die.GetID(), attrs.name,
-              attrs.encoding_form.Reference().GetOffset(), parent_die.GetID());
-        }
-
-        member_clang_type =
-            m_ast.CreateArrayType(member_array_element_type, 0, false);
-      }
-    }
-  }
-
   TypeSystemClang::RequireCompleteType(member_clang_type);
 
   clang::FieldDecl *field_decl = TypeSystemClang::AddFieldToRecordType(
diff --git a/lldb/test/Shell/SymbolFile/DWARF/incomplete-member-beyond-parent-bounds.yaml b/lldb/test/Shell/SymbolFile/DWARF/incomplete-member-beyond-parent-bounds.yaml
new file mode 100644
index 0000000000000..4e659d02b3cd4
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/incomplete-member-beyond-parent-bounds.yaml
@@ -0,0 +1,104 @@
+# This is DWARF where we placed an incomplete type
+# at an offset that is the parent DW_AT_byte_size. Check
+# that we don't report an error in such cases.
+#
+# DW_TAG_compile_unit
+#   DW_AT_name        ("main.cpp")
+#   DW_AT_language    (DW_LANG_C)
+#
+#   DW_TAG_structure_type
+#     DW_AT_name      ("Incomplete")
+#     DW_AT_external  (true)
+#
+#   DW_TAG_structure_type
+#     DW_AT_name      ("Foo")
+#     DW_AT_byte_size (0x04)
+#
+#     DW_TAG_member
+#       DW_AT_name    ("mem")
+#       DW_AT_data_member_location ("0x04")
+#       DW_AT_type    (0x00000011 "Incomplete")
+#
+#     NULL
+#
+#   NULL
+
+# RUN: yaml2obj %s > %t
+# RUN: lldb-test symbols --name=Foo --find=type %t 2>&1 | FileCheck %s
+
+# CHECK:     Found 1 types:
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+DWARF:
+  debug_str:
+    - main.cpp
+    - Incomplete
+    - Foo
+    - mem
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_udata
+        - Code:            0x2
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_external
+              Form:            DW_FORM_flag_present
+        - Code:            0x3
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x4
+          Tag:             DW_TAG_member
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+            - Attribute:       DW_AT_data_member_location
+              Form:            DW_FORM_data1
+  debug_info:
+    - Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            - Value:           0x0
+            - Value:           0x2
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0x9
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x14
+            - Value:           0x04
+        - AbbrCode:        0x4
+          Values:
+            - Value:           0x18
+            - Value:           0x11
+            - Value:           0x04
+        - AbbrCode:        0x0
+        - AbbrCode:        0x0
+...
diff --git a/lldb/test/Shell/SymbolFile/DWARF/member-beyond-parent-bounds.yaml b/lldb/test/Shell/SymbolFile/DWARF/member-beyond-parent-bounds.yaml
new file mode 100644
index 0000000000000..2ac538ed1a851
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/member-beyond-parent-bounds.yaml
@@ -0,0 +1,109 @@
+# This is malformed DWARF where we placed a non-zero sized type
+# at an offset that is larger the parent DW_AT_byte_size. Check
+# that we report an error in such cases.
+#
+# DW_TAG_compile_unit
+#   DW_AT_name        ("main.cpp")
+#   DW_AT_language    (DW_LANG_C)
+#
+#   DW_TAG_base_type
+#     DW_AT_name      ("int")
+#     DW_AT_encoding  (DW_ATE_signed)
+#     DW_AT_byte_size (0x04)
+#
+#   DW_TAG_structure_type
+#     DW_AT_name      ("Foo")
+#     DW_AT_byte_size (0x04)
+#
+#     DW_TAG_member
+#       DW_AT_name    ("mem")
+#       DW_AT_data_member_location ("0x05")
+#       DW_AT_type    (0x00000011 "int")
+#
+#     NULL
+#
+#   NULL
+
+# RUN: yaml2obj %s > %t
+# RUN: lldb-test symbols --name=Foo --find=type %t 2>&1 | FileCheck %s
+
+# CHECK: Found 1 types:
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+DWARF:
+  debug_str:
+    - main.cpp
+    - int
+    - Foo
+    - mem
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_udata
+        - Code:            0x2
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x3
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x4
+          Tag:             DW_TAG_member
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+            - Attribute:       DW_AT_data_member_location
+              Form:            DW_FORM_data1
+  debug_info:
+    - Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            - Value:           0x0
+            - Value:           0x2
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0x9
+            - Value:           0x5
+            - Value:           0x4
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x0d
+            - Value:           0x04
+        - AbbrCode:        0x4
+          Values:
+            - Value:           0x11
+            - Value:           0x11
+            - Value:           0x05
+        - AbbrCode:        0x0
+        - AbbrCode:        0x0
+...
diff --git a/lldb/test/Shell/SymbolFile/DWARF/member-on-parent-bounds.yaml b/lldb/test/Shell/SymbolFile/DWARF/member-on-parent-bounds.yaml
new file mode 100644
index 0000000000000..736697c002ee6
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/member-on-parent-bounds.yaml
@@ -0,0 +1,109 @@
+# This is malformed DWARF where we placed a non-zero sized type
+# at an offset that is the parent DW_AT_byte_size. Check
+# that we report an error in such cases.
+#
+# DW_TAG_compile_unit
+#   DW_AT_name        ("main.cpp")
+#   DW_AT_language    (DW_LANG_C)
+#
+#   DW_TAG_base_type
+#     DW_AT_name      ("int")
+#     DW_AT_encoding  (DW_ATE_signed)
+#     DW_AT_byte_size (0x04)
+#
+#   DW_TAG_structure_type
+#     DW_AT_name      ("Foo")
+#     DW_AT_byte_size (0x04)
+#
+#     DW_TAG_member
+#       DW_AT_name    ("mem")
+#       DW_AT_data_member_location ("0x04")
+#       DW_AT_type    (0x00000011 "int")
+#
+#     NULL
+#
+#   NULL
+
+# RUN: yaml2obj %s > %t
+# RUN: lldb-test symbols --name=Foo --find=type %t 2>&1 | FileCheck %s
+
+# CHECK: Found 1 types:
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+DWARF:
+  debug_str:
+    - main.cpp
+    - int
+    - Foo
+    - mem
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_udata
+        - Code:            0x2
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x3
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x4
+          Tag:             DW_TAG_member
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+            - Attribute:       DW_AT_data_member_location
+              Form:            DW_FORM_data1
+  debug_info:
+    - Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            - Value:           0x0
+            - Value:           0x2
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0x9
+            - Value:           0x5
+            - Value:           0x4
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x0d
+            - Value:           0x04
+        - AbbrCode:        0x4
+          Values:
+            - Value:           0x11
+            - Value:           0x11
+            - Value:           0x04
+        - AbbrCode:        0x0
+        - AbbrCode:        0x0
+...
diff --git a/lldb/test/Shell/SymbolFile/DWARF/union-types-no-member-location.yaml b/lldb/test/Shell/SymbolFile/DWARF/union-types-no-member-location.yaml
index fbdc626ed113f..1d1e129cdb7c0 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/union-types-no-member-location.yaml
+++ b/lldb/test/Shell/SymbolFile/DWARF/union-types-no-member-location.yaml
@@ -48,14 +48,10 @@
 # RUN: yaml2obj %s > %t
 # RUN: lldb-test symbols --name=UnionType --find=type %t > %t.stdout
 # RUN: cat %t.stdout | FileCheck --check-prefix=STDOUT %s
-# RUN: lldb-test symbols --name=UnionType --find=type %t 2> %t.stderr
-# RUN: cat %t.stderr | FileCheck --allow-empty --check-prefix=STDERR %s
 
 # STDOUT: Found 1 types:
 # STDOUT: {{(0x)?[0-9a-fA-F]+}}: Type{0x0000002b} , name = "UnionType", size = 32, compiler_type = 0x{{[0-9a-fA-F]+}} union UnionType {
 
-# STDERR-NOT: error: union-types-no-member-location.yaml.tmp 0x00000031: DW_TAG_member 'array' refers to type 0x000000000000001f which extends beyond the bounds of 0x0000002b
-
 --- !ELF
 FileHeader:
   Class:           ELFCLASS64
diff --git a/lldb/test/Shell/SymbolFile/DWARF/zero-sized-member-in-parent-bounds.yaml b/lldb/test/Shell/SymbolFile/DWARF/zero-sized-member-in-parent-bounds.yaml
new file mode 100644
index 0000000000000..a98f62cd34056
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/zero-sized-member-in-parent-bounds.yaml
@@ -0,0 +1,105 @@
+# This is DWARF where we placed a zero-sized type
+# at an offset that is the parent DW_AT_byte_size. Check
+# that we don't report an error in such cases.
+#
+# DW_TAG_compile_unit
+#   DW_AT_name        ("main.cpp")
+#   DW_AT_language    (DW_LANG_C)
+#
+#   DW_TAG_structure_type
+#     DW_AT_name      ("Bar")
+#     DW_AT_byte_size (0x00)
+#
+#   DW_TAG_structure_type
+#     DW_AT_name      ("Foo")
+#     DW_AT_byte_size (0x04)
+#
+#     DW_TAG_member
+#       DW_AT_name    ("mem")
+#       DW_AT_data_member_location ("0x04")
+#       DW_AT_type    (0x00000011 "Bar")
+#
+#     NULL
+#
+#   NULL
+
+# RUN: yaml2obj %s > %t
+# RUN: lldb-test symbols --name=Foo --find=type %t 2>&1 | FileCheck %s
+
+# CHECK:     Found 1 types:
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+DWARF:
+  debug_str:
+    - main.cpp
+    - Bar
+    - Foo
+    - mem
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_udata
+        - Code:            0x2
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x3
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x4
+          Tag:             DW_TAG_member
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+            - Attribute:       DW_AT_data_member_location
+              Form:            DW_FORM_data1
+  debug_info:
+    - Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            - Value:           0x0
+            - Value:           0x2
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0x9
+            - Value:           0x0
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x0d
+            - Value:           0x04
+        - AbbrCode:        0x4
+          Values:
+            - Value:           0x11
+            - Value:           0x11
+            - Value:           0x04
+        - AbbrCode:        0x0
+        - AbbrCode:        0x0
+...



More information about the lldb-commits mailing list