From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2205) id 40D15384D184; Tue, 30 Aug 2022 08:22:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 40D15384D184 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1661847760; bh=dnlG/6+0CBXyqVNvPWuqFaY5w1QeBKdG6zlBpR8IBd8=; h=From:To:Subject:Date:From; b=d7PJpsTe/1nSd+4colN+aUHD8N6nlisRdl9FeMwOPEWFNmMZTJJnHRMI0f4DggZjX VWb1Yn0p88C4xt3hKhjc/yYIWSpcI2y+ff0UPsMe07nmCKOlJC1gCYmkgu4duDwQBO XQiPm7lM0myBmjgKv9Myoju+pz7D4EUxMTCcobD4= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom de Vries To: gdb-cvs@sourceware.org Subject: [binutils-gdb] [gdb/symtab] Fix assert in set_length X-Act-Checkin: binutils-gdb X-Git-Author: Tom de Vries X-Git-Refname: refs/heads/master X-Git-Oldrev: 28b5cde22b1a858b8c05da0f03ba37c670798298 X-Git-Newrev: 1c04f72368c925288a6f1b1abb0dbc31a60d2f49 Message-Id: <20220830082240.40D15384D184@sourceware.org> Date: Tue, 30 Aug 2022 08:22:40 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D1c04f72368c9= 25288a6f1b1abb0dbc31a60d2f49 commit 1c04f72368c925288a6f1b1abb0dbc31a60d2f49 Author: Tom de Vries Date: Tue Aug 30 10:22:28 2022 +0200 [gdb/symtab] Fix assert in set_length =20 When running the included test-case, we run into: ... (gdb) break _start^M read.h:309: internal-error: set_length: \ Assertion `m_length =3D=3D length' failed.^M ... =20 The problem is that while there are two CUs: ... $ readelf -wi debug-names-missing-cu | grep @ Compilation Unit @ offset 0x0: Compilation Unit @ offset 0x2d: ... the CU table in the .debug_names section only contains the first one: ... CU table: [ 0] 0x0 ... =20 The incomplete CU table makes create_cus_from_debug_names_list set the = size of the CU at 0x0 to the actual size of both CUs combined. =20 This eventually leads to the assert, when we read the actual size from = the CU header. =20 While having an incomplete CU table in a .debug_names section is incorr= ect, we need a better failure mode than asserting. =20 The easiest way to fix this is to set the length to 0 (meaning: unkown)= in create_cus_from_debug_names_list. =20 This makes the failure mode to accept the incomplete CU table, but to i= gnore the missing CU. =20 It would be nice to instead reject the .debug_names index, and build a complete CU list, but the point where we find this out is well after dwarf2_initialize_objfile, so it looks rather intrusive to restart at t= hat point. =20 Tested on x86_64-linux. =20 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D29453 Diff: --- gdb/dwarf2/read.c | 4 +- .../gdb.dwarf2/debug-names-missing-cu.exp | 80 ++++++++++++++++++= ++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 84faeb45238..6c6ca96f8d9 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -4655,7 +4655,9 @@ create_cus_from_debug_names_list (dwarf2_per_bfd *per= _bfd, " ignoring .debug_names.")); return false; } - const ULONGEST length =3D sect_off_next - sect_off_prev; + /* Note: we're not using length =3D sect_off_next - sect_off_prev, + to gracefully handle an incomplete CU list. */ + const ULONGEST length =3D 0; dwarf2_per_cu_data_up per_cu =3D create_cu_from_index_list (per_bfd, §ion, is_dwz, sect_off_prev, length); diff --git a/gdb/testsuite/gdb.dwarf2/debug-names-missing-cu.exp b/gdb/test= suite/gdb.dwarf2/debug-names-missing-cu.exp new file mode 100644 index 00000000000..f70debd35ad --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/debug-names-missing-cu.exp @@ -0,0 +1,80 @@ +# Copyright 2022 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 . + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile _start.c debug-names.S + +set func_info_vars \ + [get_func_info _start [list debug additional_flags=3D-nostartfiles]] + +# Create the DWARF. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble { + filename $asm_file + add_dummy_cus 0 +} { + global func_info_vars + foreach var $func_info_vars { + global $var + } + + cu { label cu_label } { + compile_unit {{language @DW_LANG_C}} { + subprogram { + {DW_AT_name _start} + {DW_AT_low_pc $_start_start DW_FORM_addr} + {DW_AT_high_pc $_start_end DW_FORM_addr} + } + base_type { + {name int} + {byte_size 4 sdata} + {encoding @DW_ATE_signed} + } + } + } + + # This CU is missing from the cu list in .debug_names. + cu {} { + } + + debug_names {} { + cu cu_label + name _start subprogram cu_label 0xEDDB6232 + name int base_type cu_label 0xB888030 + } +} + +if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfi= le}" \ + [list additional_flags=3D-nostartfiles]] { + return -1 +} + +# Verify that .debug_names section is not ignored. +set index [have_index $binfile] +gdb_assert { [string equal $index "debug_names"] } ".debug_names used" + +# Verify that initially no symtab is expanded. +gdb_test_no_output "maint info symtabs" + +# Verify that _start is found in the debuginfo, rather than in the minimal +# symbols, which would result instead in: +# $1 =3D {} $hex <_start> +gdb_test "print _start" " =3D {void \\(\\)} $hex <_start>"