diff options
author | Tom de Vries <tdevries@suse.de> | 2024-09-24 10:50:44 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-09-24 10:50:44 +0200 |
commit | 6848938272157eb6532c189d6fcebec9d2dc33e8 (patch) | |
tree | 27b005aaa15b1f62644dee212bab724f5d8d091f /gdb/testsuite/gdb.dwarf2 | |
parent | 510ecbcdfbf3c90761eb9f1d08d63a84999a8b9b (diff) | |
download | gdb-6848938272157eb6532c189d6fcebec9d2dc33e8.zip gdb-6848938272157eb6532c189d6fcebec9d2dc33e8.tar.gz gdb-6848938272157eb6532c189d6fcebec9d2dc33e8.tar.bz2 |
[gdb/symtab] Fix segfault on invalid debug info
While looking at PR symtab/31478 (a problem in the cooked indexer with invalid
dwarf) it occurred to me that I could trigger a similar problem using:
...
Compilation Unit @ offset 0xb2:
Length: 0x1f (32-bit)
Version: 4
Abbrev Offset: 0x6c
Pointer Size: 8
<0><bd>: Abbrev Number: 1 (DW_TAG_compile_unit)
<be> DW_AT_language : 2 (non-ANSI C)
<1><bf>: Abbrev Number: 2 (DW_TAG_subprogram)
<c0> DW_AT_low_pc : 0x4004a7
<c8> DW_AT_high_pc : 0x4004b2
<d0> DW_AT_specification: <0xd5>
<1><d4>: Abbrev Number: 0
Compilation Unit @ offset 0xd5:
Length: 0x7 (32-bit)
Version: 4
Abbrev Offset: 0x7f
Pointer Size: 8
...
and indeed I get:
...
$ gdb -q -batch outputs/gdb.dwarf2/dw2-inter-cu-error-2/dw2-inter-cu-error-2
Fatal signal: Segmentation fault
...
The problem is that we're calling prepare_one_comp_unit with cu == nullptr and
comp_unit_die == nullptr here in cooked_indexer::ensure_cu_exists:
...
cutu_reader new_reader (per_cu, per_objfile, nullptr, nullptr, false,
m_index_storage->get_abbrev_cache ());
prepare_one_comp_unit (new_reader.cu, new_reader.comp_unit_die,
language_minimal);
...
Fix this by bailing out for various types of dummy CUs:
...
if (new_reader.dummy_p || new_reader.comp_unit_die == nullptr
|| !new_reader.comp_unit_die->has_children)
return nullptr;
...
Also make sure in scan_attributes that this triggers a dwarf error:
...
$ gdb -q -batch dw2-inter-cu-error-2
DWARF Error: cannot follow reference to DIE at 0xd5 \
[in module dw2-inter-cu-error-2]
...
With target board readnow, the test-case triggers an assertion failure in
follow_die_offset, so fix this by throwing the same dwarf error.
While we're at it, make the other check for dummy CUs in
cooked_indexer::ensure_cu_exists more robust by adding an intermediate test
for comp_unit_die:
...
- if (result->dummy_p || !result->comp_unit_die->has_children)
+ if (result->dummy_p || result->comp_unit_die == nullptr
+ || !result->comp_unit_die->has_children)
return nullptr;
...
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/testsuite/gdb.dwarf2')
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp new file mode 100644 index 0000000..585fd54 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp @@ -0,0 +1,51 @@ +# Copyright 2024 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/>. + +# Check that GDB doesn't crash on invalid dwarf, specifically an inter-CU +# reference pointing to a dummy CU. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile main.c .S + +# Create the DWARF. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + declare_labels label1 + + cu {} { + compile_unit {{language @DW_LANG_C}} { + subprogram { + {MACRO_AT_range { main }} + {DW_AT_specification %$label1} + } + } + } + + label1: cu {} { + } +} + +if [prepare_for_testing "failed to prepare" $testfile \ + [list $asm_file $srcfile] {nodebug}] { + return -1 +} + +gdb_assert \ + { [regexp "DWARF Error: cannot follow reference" $gdb_file_cmd_msg] } \ + "Error message" |