[v3] gdb/dwarf: fix assert failed for missing containing type
Commit Message
gdb/dwarf: fix assert failed for missing containing type
This patch fixes an assertion failure that occurs when handling
missing type units.
If the TU referenced by a `DW_AT_containing_type` cannot be
found (e.g., due to DWP overflow), the error type returned from the
DWARF reader is incorrectly passed to `set_type_vptr_fieldno`, causing
an assertion failure:
gdb/gdbtypes.c:1919: internal-error: internal_type_vptr_fieldno: Assertion `type->code () == TYPE_CODE_STRUCT || type->code () == TYPE_CODE_UNION' failed.
---
gdb/dwarf2/read.c | 8 ++-
.../gdb.dwarf2/missing-containing-type.exp | 71 +++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/missing-containing-type.exp
Comments
Hi,
On 12/24/25 11:02 PM, Sockke wrote:
> gdb/dwarf: fix assert failed for missing containing type
>
> This patch fixes an assertion failure that occurs when handling
> missing type units.
Thank you for the revision. In an effort to get this moving, Simon's
question about an assignment aside
[https://inbox.sourceware.org/gdb-patches/678d6038-2d42-4167-9b10-891317a669c3@simark.ca/],
this
patch is looking near complete/ready.
I just have a comment or two.
> diff --git a/gdb/testsuite/gdb.dwarf2/missing-containing-type.exp b/gdb/testsuite/gdb.dwarf2/missing-containing-type.exp
> new file mode 100644
> index 00000000..301c8432
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/missing-containing-type.exp
> @@ -0,0 +1,71 @@
> +# Copyright 2025 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +load_lib dwarf.exp
> +
> +# This test can only be run on targets which support DWARF-2 and use gas.
> +require dwarf2_support
> +
> +require allow_cplus_tests
> +
> +standard_testfile main.c -dw4.S
> +
> +# Make some DWARF for the test.
> +set asm_file [standard_output_file $srcfile2]
> +Dwarf::assemble $asm_file {
> + cu {} {
> + DW_TAG_compile_unit {
> + DW_AT_language @DW_LANG_C_plus_plus
> + } {
> + declare_labels container_decl abase_client_type
> + DW_TAG_namespace {
> + DW_AT_name NS
> + } {
> + container_decl: DW_TAG_class_type {
> + DW_AT_signature 0x1122334455667788 DW_FORM_ref_sig8
> + DW_AT_declaration 1 DW_FORM_flag
> + } {
> + abase_client_type: DW_TAG_class_type {
> + DW_AT_name C
> + DW_AT_byte_size 0x170 DW_FORM_sdata
> + DW_AT_containing_type :$container_decl
> + } {
> + DW_TAG_subprogram { DW_AT_name "~C" }
> + }
> + }
> + }
> + }
> + }
> + # The referenced TU has been lost.
> + #tu {} 0x1122334455667788 container_type {
> + # DW_TAG_type_unit {
> + # DW_AT_language @DW_LANG_C_plus_plus
> + # } {
> + # DW_AT_container_type: class_type {
> + # {DW_AT_name C}
> + # {DW_AT_byte_size 1 sdata}
> + # }
> + # }
> + #}
> +}
> +
> +
> +if { [prepare_for_testing "failed to prepare" ${testfile} \
> + [list $srcfile $asm_file] {nodebug}] } {
> + return
> +}
> +
> +gdb_test_no_output "set language c++"
> +
> +gdb_test "ptype NS::C" "No symbol .*"
Please add a comment explaining that this used to cause gdb to
assert.
And please fix the result of gdb.src/pre-commit.exp. There are
simple whitespace errors to sort out:
$ make check TESTS=gdb.src/pre-commit.exp
[snip]
Running
/home/keiths/work/gdb/branches/sockke-assert-missing-containing_type/linux/gdb/testsuite/../../../src/gdb/testsuite/gdb.src/pre-commit.exp
...
FAIL: gdb.src/pre-commit.exp: pre-commit checks
=== gdb Summary ===
# of unexpected failures 1
Otherwise, LGTM.
Reviewed-By: Keith Seitz <keiths@redhat.com>
Keith
On 1/15/26 12:12 PM, Keith Seitz wrote:
> Hi,
>
> On 12/24/25 11:02 PM, Sockke wrote:
>> gdb/dwarf: fix assert failed for missing containing type
>>
>> This patch fixes an assertion failure that occurs when handling
>> missing type units.
>
> Thank you for the revision. In an effort to get this moving, Simon's
> question about an assignment aside [https://inbox.sourceware.org/gdb-patches/678d6038-2d42-4167-9b10-891317a669c3@simark.ca/], this
> patch is looking near complete/ready.
>
> I just have a comment or two.
>
>> diff --git a/gdb/testsuite/gdb.dwarf2/missing-containing-type.exp b/gdb/testsuite/gdb.dwarf2/missing-containing-type.exp
>> new file mode 100644
>> index 00000000..301c8432
>> --- /dev/null
>> +++ b/gdb/testsuite/gdb.dwarf2/missing-containing-type.exp
>> @@ -0,0 +1,71 @@
>> +# Copyright 2025 Free Software Foundation, Inc.
>> +
>> +# This program is free software; you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation; either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +load_lib dwarf.exp
>> +
>> +# This test can only be run on targets which support DWARF-2 and use gas.
>> +require dwarf2_support
>> +
>> +require allow_cplus_tests
>> +
>> +standard_testfile main.c -dw4.S
>> +
>> +# Make some DWARF for the test.
>> +set asm_file [standard_output_file $srcfile2]
>> +Dwarf::assemble $asm_file {
>> + cu {} {
>> + DW_TAG_compile_unit {
>> + DW_AT_language @DW_LANG_C_plus_plus
>> + } {
>> + declare_labels container_decl abase_client_type
>> + DW_TAG_namespace {
>> + DW_AT_name NS
>> + } {
>> + container_decl: DW_TAG_class_type {
>> + DW_AT_signature 0x1122334455667788 DW_FORM_ref_sig8
>> + DW_AT_declaration 1 DW_FORM_flag
>> + } {
>> + abase_client_type: DW_TAG_class_type {
>> + DW_AT_name C
>> + DW_AT_byte_size 0x170 DW_FORM_sdata
>> + DW_AT_containing_type :$container_decl
>> + } {
>> + DW_TAG_subprogram { DW_AT_name "~C" }
>> + }
>> + }
>> + }
>> + }
>> + }
>> + # The referenced TU has been lost.
>> + #tu {} 0x1122334455667788 container_type {
>> + # DW_TAG_type_unit {
>> + # DW_AT_language @DW_LANG_C_plus_plus
>> + # } {
>> + # DW_AT_container_type: class_type {
>> + # {DW_AT_name C}
>> + # {DW_AT_byte_size 1 sdata}
>> + # }
>> + # }
>> + #}
>> +}
>> +
>> +
>> +if { [prepare_for_testing "failed to prepare" ${testfile} \
>> + [list $srcfile $asm_file] {nodebug}] } {
>> + return
>> +}
>> +
>> +gdb_test_no_output "set language c++"
>> +
>> +gdb_test "ptype NS::C" "No symbol .*"
>
> Please add a comment explaining that this used to cause gdb to
> assert.
>
> And please fix the result of gdb.src/pre-commit.exp. There are
> simple whitespace errors to sort out:
>
> $ make check TESTS=gdb.src/pre-commit.exp
> [snip]
> Running /home/keiths/work/gdb/branches/sockke-assert-missing-containing_type/linux/gdb/testsuite/../../../src/gdb/testsuite/gdb.src/pre-commit.exp ...
> FAIL: gdb.src/pre-commit.exp: pre-commit checks
>
> === gdb Summary ===
>
> # of unexpected failures 1
When you apply the patch, git tells you about these (I guess they are
the same):
Applying: gdb/dwarf: fix assert failed for missing containing type
Patch failed at 0001 gdb/dwarf: fix assert failed for missing containing type
/home/smarchi/src/binutils-gdb/.git/rebase-apply/patch:63: indent with spaces.
DW_AT_language @DW_LANG_C_plus_plus
/home/smarchi/src/binutils-gdb/.git/rebase-apply/patch:65: indent with spaces.
declare_labels container_decl abase_client_type
/home/smarchi/src/binutils-gdb/.git/rebase-apply/patch:66: indent with spaces.
DW_TAG_namespace {
/home/smarchi/src/binutils-gdb/.git/rebase-apply/patch:67: indent with spaces.
DW_AT_name NS
/home/smarchi/src/binutils-gdb/.git/rebase-apply/patch:68: indent with spaces.
} {
Otherwise, it might be a bit easier to see the results if you run
pre-commit directly:
$ pre-commit run --all-files
Instructions on how to set up pre-commit:
https://sourceware.org/gdb/wiki/DeveloperTips#Setting_up_pre-commit
Simon
@@ -11549,10 +11549,16 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
"not found when defining class '%s'"),
type->name () ? type->name () : "");
}
- else
+ else if (t->code () == TYPE_CODE_STRUCT
+ || t->code () == TYPE_CODE_UNION)
{
set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t));
}
+ else
+ {
+ complaint (_("unable to retrieve the vptr from "
+ "this type '%s'"), TYPE_ERROR_NAME (t));
+ }
}
else if (cu->producer_is_xlc ())
{
new file mode 100644
@@ -0,0 +1,71 @@
+# Copyright 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+require allow_cplus_tests
+
+standard_testfile main.c -dw4.S
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ cu {} {
+ DW_TAG_compile_unit {
+ DW_AT_language @DW_LANG_C_plus_plus
+ } {
+ declare_labels container_decl abase_client_type
+ DW_TAG_namespace {
+ DW_AT_name NS
+ } {
+ container_decl: DW_TAG_class_type {
+ DW_AT_signature 0x1122334455667788 DW_FORM_ref_sig8
+ DW_AT_declaration 1 DW_FORM_flag
+ } {
+ abase_client_type: DW_TAG_class_type {
+ DW_AT_name C
+ DW_AT_byte_size 0x170 DW_FORM_sdata
+ DW_AT_containing_type :$container_decl
+ } {
+ DW_TAG_subprogram { DW_AT_name "~C" }
+ }
+ }
+ }
+ }
+ }
+ # The referenced TU has been lost.
+ #tu {} 0x1122334455667788 container_type {
+ # DW_TAG_type_unit {
+ # DW_AT_language @DW_LANG_C_plus_plus
+ # } {
+ # DW_AT_container_type: class_type {
+ # {DW_AT_name C}
+ # {DW_AT_byte_size 1 sdata}
+ # }
+ # }
+ #}
+}
+
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return
+}
+
+gdb_test_no_output "set language c++"
+
+gdb_test "ptype NS::C" "No symbol .*"