gdb: handle invalid DWARF when compilation unit is missing
Replace an abort call in process_psymtab_comp_unit with a real error, and add a test to cover this case. The case is question is when badly formed DWARF is missing a DW_TAG_compile_unit, DW_TAG_partial_unit, or DW_TAG_type_unit as its top level tag. I then tested with --target_board=readnow and added additional code to also validate the top-level tag in this case. I added an assert that would trigger for the readnow case before I added the fix. I suspect there's lots of places where badly formed DWARF could result in the builder being nullptr when it shouldn't be, but I only added this one assert, as this is the one that would have helped me in this case. gdb/ChangeLog: * dwarf2/read.c (process_psymtab_comp_unit): Replace abort with an error. (process_full_comp_unit): Validate the top-level tag before processing the first DIE. (read_func_scope): Ensure we have a valid builder. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-missing-cu-tag.c: New file. * gdb.dwarf2/dw2-missing-cu-tag.exp: New file.
This commit is contained in:
parent
46fec6428e
commit
702cf3f5df
@ -1,3 +1,11 @@
|
||||
2021-03-22 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* dwarf2/read.c (process_psymtab_comp_unit): Replace abort with an
|
||||
error.
|
||||
(process_full_comp_unit): Validate the top-level tag before
|
||||
processing the first DIE.
|
||||
(read_func_scope): Ensure we have a valid builder.
|
||||
|
||||
2021-03-22 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* objc-lang.c (objc_demangle): Renamed to
|
||||
|
@ -7737,7 +7737,10 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
|
||||
this_cu->unit_type = DW_UT_type;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
|
||||
dwarf_tag_name (reader.comp_unit_die->tag),
|
||||
sect_offset_str (reader.cu->per_cu->sect_off),
|
||||
objfile_name (per_objfile->objfile));
|
||||
}
|
||||
|
||||
if (reader.dummy_p)
|
||||
@ -9994,6 +9997,21 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
|
||||
|
||||
dwarf2_find_base_address (cu->dies, cu);
|
||||
|
||||
/* Before we start reading the top-level DIE, ensure it has a valid tag
|
||||
type. */
|
||||
switch (cu->dies->tag)
|
||||
{
|
||||
case DW_TAG_compile_unit:
|
||||
case DW_TAG_partial_unit:
|
||||
case DW_TAG_type_unit:
|
||||
break;
|
||||
default:
|
||||
error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
|
||||
dwarf_tag_name (cu->dies->tag),
|
||||
sect_offset_str (cu->per_cu->sect_off),
|
||||
objfile_name (per_objfile->objfile));
|
||||
}
|
||||
|
||||
/* Do line number decoding in read_file_scope () */
|
||||
process_die (cu->dies, cu);
|
||||
|
||||
@ -13628,6 +13646,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
}
|
||||
}
|
||||
|
||||
gdb_assert (cu->get_builder () != nullptr);
|
||||
newobj = cu->get_builder ()->push_context (0, lowpc);
|
||||
newobj->name = new_symbol (die, read_type_die (die, cu), cu,
|
||||
(struct symbol *) templ_func);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2021-03-22 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* gdb.dwarf2/dw2-missing-cu-tag.c: New file.
|
||||
* gdb.dwarf2/dw2-missing-cu-tag.exp: New file.
|
||||
|
||||
2021-03-22 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* gdb.dwarf2/dw2-using-debug-str.c: New file.
|
||||
|
25
gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.c
Normal file
25
gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2021 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/>. */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
asm ("main_label: .globl main_label");
|
||||
|
||||
return 0;
|
||||
}
|
76
gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.exp
Normal file
76
gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.exp
Normal file
@ -0,0 +1,76 @@
|
||||
# Copyright 2021 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/>.
|
||||
|
||||
# This test creates some invalid DWARF, compiles this into an
|
||||
# executable, then tries to load the executable using the 'file'
|
||||
# command. We expect to see an error from the DWARF parser.
|
||||
|
||||
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 .c -dw.S
|
||||
|
||||
set asm_file [standard_output_file $srcfile2]
|
||||
Dwarf::assemble $asm_file {
|
||||
cu {} {
|
||||
# We should have either one of DW_TAG_compile_unit,
|
||||
# DW_TAG_partial_unit, or DW_TAG_type_unit here.
|
||||
subprogram {
|
||||
{external 1 flag}
|
||||
{MACRO_AT_func {main}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Don't use prepare_for_testing here as we want to manually run the
|
||||
# file command (so we can check its output).
|
||||
if {[build_executable "failed to build executable" $testfile \
|
||||
[list $srcfile $asm_file] {nodebug quiet}]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Restart with no executable.
|
||||
clean_restart
|
||||
|
||||
# This pattern is hit when GDB does not use -readnow (i.e. the default
|
||||
# behaviour).
|
||||
set pattern1 \
|
||||
[multi_line \
|
||||
"Reading symbols from \[^\r\n\]+" \
|
||||
"Dwarf Error: unexpected tag 'DW_TAG_subprogram' at offset $hex \\\[\[^\r\n\]+\\\]" \
|
||||
"\\(No debugging symbols \[^\r\n\]+\\)"]
|
||||
|
||||
# This pattern is hit when GDB does use -readnow (e.g. running with
|
||||
# --target_board=readnow).
|
||||
set pattern2 \
|
||||
[multi_line \
|
||||
"Reading symbols from \[^\r\n\]+" \
|
||||
"Expanding full symbols from \[^\r\n\]+" \
|
||||
"Dwarf Error: unexpected tag 'DW_TAG_subprogram' at offset $hex \\\[\[^\r\n\]+\\\]"]
|
||||
|
||||
# Load the executable, we expect an error from the DWARF parser.
|
||||
gdb_test_multiple "file $binfile" "file $testfile" {
|
||||
-wrap -re $pattern1 {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
-re -wrap "$pattern2" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user