binutils-gdb/gdb/dwarf2/macro.h
Simon Marchi f6c4a82abd gdb: avoid dereferencing empty str_offsets_base optional in dwarf_decode_macros
Since 4d7188abfd ("gdbsupport: add debug assertions in
gdb::optional::get"), some macro-related tests fail on Ubuntu 20.04 with
the system gcc 9.3.0 compiler when building with _GLIBCXX_DEBUG.  For
example, gdb.base/info-macros.exp results in:

   (gdb) break -qualified main
   /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/gdb_optional.h:206: internal-error: T& gdb::optional<T>::get() [with T = long unsigned int]: Assertion `this->has_value ()' failed.

The binary contains DWARF 4 debug info and includes a pre-standard
(pre-DWARF 5) .debug_macro section.  The CU doesn't have a
DW_AT_str_offsets_base attribute (which doesn't exist in DWARF 4).  The
field dwarf2_cu::str_offsets_base is therefore empty.  At
dwarf2/read.c:24138, we unconditionally read the value in the optional,
which triggers the assertion shown above.

The same thing happens when building the test program with DWARF 5 with
the same gcc compiler, as that version of gcc doesn't use indirect
string forms, even with DWARF 5.  So it still doesn't add a
DW_AT_str_offsets_base attribute on the CU.

Fix that by propagating down a gdb::optional<ULONGEST> for the str
offsets base instead of ULONGEST.  That value is only used in
dwarf_decode_macro_bytes, when encountering an "strx" macro operation
(DW_MACRO_define_strx or DW_MACRO_undef_strx).  Add a check there that
we indeed have a value in the optional before reading it.  This is
unlikely to happen, but could happen in theory with an erroneous file
that uses DW_MACRO_define_strx but does not provide a
DW_AT_str_offsets_base (in practice, some things would probably have
failed before and stopped processing of debug info).  I tested the
complaint by inverting the condition and using a clang-compiled binary,
which uses the strx operators.  This is the result:

    During symbol reading: use of DW_MACRO_define_strx with unknown string offsets base [in module /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/info-macros/info-macros]

The test now passes cleanly with the setup mentioned above, and the
testsuite looks on par with how it was before 4d7188abfd.

Change-Id: I7ebd2724beb7b9b4178872374c2a177aea696e77
2021-08-04 15:26:22 -04:00

37 lines
1.2 KiB
C

/* DWARF macro support for GDB.
Copyright (C) 2003-2021 Free Software Foundation, Inc.
This file is part of GDB.
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/>. */
#ifndef GDB_DWARF2_MACRO_H
#define GDB_DWARF2_MACRO_H
struct buildsym_compunit;
extern void dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
buildsym_compunit *builder,
const dwarf2_section_info *section,
const struct line_header *lh,
unsigned int offset_size,
unsigned int offset,
dwarf2_section_info *str_section,
dwarf2_section_info *str_offsets_section,
gdb::optional<ULONGEST> str_offsets_base,
int section_is_gnu);
#endif /* GDB_DWARF2_MACRO_H */