Skip to content

Conversation

@Michael137
Copy link
Member

@Michael137 Michael137 commented Sep 22, 2025

First time check 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 check is getting quite convoluted, and all it does is turn an array[1] into an array[0] type when it is deemed correct. At this point the workaround probably never fires, apart from actually valid codegen. This patch removes the special conditions and emits the error specifically in those cases where we know the DWARF is malformed.

Added some shell tests for the error case.

@Michael137 Michael137 force-pushed the lldb/dwarf-redundant-condition branch 2 times, most recently from 1c07ed2 to 55de305 Compare September 29, 2025 14:02
…formed 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.
@Michael137 Michael137 force-pushed the lldb/dwarf-redundant-condition branch from 55de305 to 23a1d70 Compare September 29, 2025 14:39
@Michael137 Michael137 changed the title DRAFT: [lldb][DWARFASTParserClang] Remove old workaround [lldb][DWARFASTParserClang] Simplify obsolete error condition for malformed array member type offsets Sep 29, 2025
@Michael137 Michael137 marked this pull request as ready for review September 29, 2025 14:39
@llvmbot llvmbot added the lldb label Sep 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 29, 2025

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

Changes

First time check was introduced in Michael137@fa3ab45 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 check is getting quite convoluted, and all it does is turn an array[1] into an array[0] type when it is deemed correct. At this point the workaround probably never fires, apart from actually valid codegen. This patch removes the special conditions and emits the error specifically in those cases where we know the DWARF is malformed.

Added some shell tests for the error case.


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

6 Files Affected:

  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (-37)
  • (added) lldb/test/Shell/SymbolFile/DWARF/incomplete-member-beyond-parent-bounds.yaml (+104)
  • (added) lldb/test/Shell/SymbolFile/DWARF/member-beyond-parent-bounds.yaml (+109)
  • (added) lldb/test/Shell/SymbolFile/DWARF/member-on-parent-bounds.yaml (+109)
  • (modified) lldb/test/Shell/SymbolFile/DWARF/union-types-no-member-location.yaml (-4)
  • (added) lldb/test/Shell/SymbolFile/DWARF/zero-sized-member-in-parent-bounds.yaml (+105)
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
+...

Copy link
Collaborator

@adrian-prantl adrian-prantl left a comment

Choose a reason for hiding this comment

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

That looks like it outlived its usefulness.

@Michael137 Michael137 merged commit eef7a76 into llvm:main Sep 29, 2025
12 checks passed
@Michael137 Michael137 deleted the lldb/dwarf-redundant-condition branch September 29, 2025 20:05
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
…formed array member type offsets (llvm#160132)

First time check 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 check is getting quite convoluted, and all it does is turn an
`array[1]` into an `array[0]` type when it is deemed correct. At this
point the workaround probably never fires, apart from actually valid
codegen. This patch removes the special conditions and emits the error
specifically in those cases where we know the DWARF is malformed.

Added some shell tests for the error case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants