From cc12ce380e8dab7e3cee8ecad29db6e9bb36a8fa Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 23 Jul 2015 09:21:48 -0700 Subject: [PATCH] Fix crash when reading dummy CUs. Dummy CUs are used by the incremental linker to pre-allocate space in the output file. They have a DWARF header but no contents. gdb/ChangeLog: * dwarf2read.c (dwarf2_per_cu_data): Add comment. (load_cu): Handle dummy CUs. (dw2_do_instantiate_symtab, process_queuef): Ditto. (dwarf2_fetch_die_loc_sect_off, dwarf2_fetch_constant_bytes): Ditto. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-dummy-cu.S: New file. * gdb.dwarf2/dw2-dummy-cu.exp: New file. --- gdb/ChangeLog | 7 ++++ gdb/dwarf2read.c | 29 ++++++++++++++--- gdb/testsuite/ChangeLog | 5 +++ gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S | 33 +++++++++++++++++++ gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.exp | 39 +++++++++++++++++++++++ 5 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ecc7f556f05..ed9e302e2d2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2015-07-23 Doug Evans + + * dwarf2read.c (dwarf2_per_cu_data): Add comment. + (load_cu): Handle dummy CUs. + (dw2_do_instantiate_symtab, process_queuef): Ditto. + (dwarf2_fetch_die_loc_sect_off, dwarf2_fetch_constant_bytes): Ditto. + 2015-07-23 Ciro Santilli (tiny patch) * py-linetable.c (ltpy_get_all_source_lines): Adjust function diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f44095683fb..24a4022c4a7 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -610,7 +610,8 @@ struct dwarf2_per_cu_data struct dwarf2_section_info *section; /* Set to non-NULL iff this CU is currently loaded. When it gets freed out - of the CU cache it gets reset to NULL again. */ + of the CU cache it gets reset to NULL again. This is left as NULL for + dummy CUs (a CU header, but nothing else). */ struct dwarf2_cu *cu; /* The corresponding objfile. @@ -2655,7 +2656,8 @@ load_cu (struct dwarf2_per_cu_data *per_cu) else load_full_comp_unit (per_cu, language_minimal); - gdb_assert (per_cu->cu != NULL); + if (per_cu->cu == NULL) + return; /* Dummy CU. */ dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu); } @@ -2685,6 +2687,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) that may badly handle TUs, load all the TUs in that DWO as well. http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */ if (!per_cu->is_debug_types + && per_cu->cu != NULL && per_cu->cu->dwo_unit != NULL && dwarf2_per_objfile->index_table != NULL && dwarf2_per_objfile->index_table->version <= 7 @@ -7544,9 +7547,11 @@ process_queue (void) may load a new CU, adding it to the end of the queue. */ for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item) { - if (dwarf2_per_objfile->using_index - ? !item->per_cu->v.quick->compunit_symtab - : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin)) + if ((dwarf2_per_objfile->using_index + ? !item->per_cu->v.quick->compunit_symtab + : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin)) + /* Skip dummy CUs. */ + && item->per_cu->cu != NULL) { struct dwarf2_per_cu_data *per_cu = item->per_cu; unsigned int debug_print_threshold; @@ -20017,6 +20022,13 @@ dwarf2_fetch_die_loc_sect_off (sect_offset offset, if (per_cu->cu == NULL) load_cu (per_cu); cu = per_cu->cu; + if (cu == NULL) + { + /* We shouldn't get here for a dummy CU, but don't crash on the user. + Instead just throw an error, not much else we can do. */ + error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"), + offset.sect_off, objfile_name (per_cu->objfile)); + } die = follow_die_offset (offset, per_cu->is_dwz, &cu); if (!die) @@ -20118,6 +20130,13 @@ dwarf2_fetch_constant_bytes (sect_offset offset, if (per_cu->cu == NULL) load_cu (per_cu); cu = per_cu->cu; + if (cu == NULL) + { + /* We shouldn't get here for a dummy CU, but don't crash on the user. + Instead just throw an error, not much else we can do. */ + error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"), + offset.sect_off, objfile_name (per_cu->objfile)); + } die = follow_die_offset (offset, per_cu->is_dwz, &cu); if (!die) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index b2c1635d242..282810a88fd 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-23 Doug Evans + + * gdb.dwarf2/dw2-dummy-cu.S: New file. + * gdb.dwarf2/dw2-dummy-cu.exp: New file. + 2015-07-23 Pierre-Marie de Rodat * gdb.ada/var_arr_typedef.exp: New testcase. diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S b/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S new file mode 100644 index 00000000000..fa3156138f0 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S @@ -0,0 +1,33 @@ +/* Copyright 2015 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 . */ + + .text +main: + .4byte 0 +main_end: + + .section .debug_info + .4byte .Ldebug_info_end - 1f /* Length of Compilation Unit Info */ +1: + .2byte 0x2 /* DWARF version number */ + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ + .byte 0x4 /* Pointer Size (in bytes) */ + + /* Nothing else, this is a dummy die. */ +.Ldebug_info_end: + + .section .debug_abbrev +.Ldebug_abbrev0: + .byte 0x0 diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.exp b/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.exp new file mode 100644 index 00000000000..a5f6ca54205 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.exp @@ -0,0 +1,39 @@ +# Copyright 2015 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 .S +set executable ${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } { + return -1 +} + +set saved_gdbflags $GDBFLAGS +set GDBFLAGS "$GDBFLAGS -readnow" + +clean_restart $executable + +# Something simple to verify gdb didn't crash, and has read in whatever symbol +# info is there. +gdb_test "info fun main" "main_end" + +set GDBFLAGS $saved_gdbflags -- 2.30.2