[gdb/symtab] Fix segfault in search_one_symtab
authorTom de Vries <tdevries@suse.de>
Mon, 29 Nov 2021 15:19:16 +0000 (16:19 +0100)
committerTom de Vries <tdevries@suse.de>
Mon, 29 Nov 2021 15:19:16 +0000 (16:19 +0100)
commit49fa1332a69bc4b09d2cc7db587e27ea30f2a29d
tree1bf3c62ec0c6c9a9220221906aeb24c1bc322ce7
parent8fee99c3c8e25f2708bddde345c192dd2f3e7e08
[gdb/symtab] Fix segfault in search_one_symtab

PR28539 describes a segfault in lambda function search_one_symtab due to
psymbol_functions::expand_symtabs_matching calling expansion_notify with a
nullptr symtab:
...
          struct compunit_symtab *symtab =
            psymtab_to_symtab (objfile, ps);

          if (expansion_notify != NULL)
            if (!expansion_notify (symtab))
              return false;
...

This happens as follows.  The partial symtab ps is a dwarf2_include_psymtab
for some header file:
...
(gdb) p ps.filename
$5 = 0x64fcf80 "/usr/include/c++/11/bits/stl_construct.h"
...

The includer of ps is a shared symtab for a partial unit, with as user:
...
(gdb) p ps.includer().user.filename
$11 = 0x64fc9f0 \
  "/usr/src/debug/llvm13-13.0.0-1.2.x86_64/tools/clang/lib/AST/Decl.cpp"
...

The call to psymtab_to_symtab expands the Decl.cpp symtab (and consequently
the shared symtab), but returns nullptr because:
...
struct dwarf2_include_psymtab : public partial_symtab
{
  ...
  compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
  {
    return nullptr;
  }
...

Fix this by returning the Decl.cpp symtab instead, which fixes the segfault
in the PR.

Tested on x86_64-linux.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28539
gdb/dwarf2/read.c
gdb/psymtab.c
gdb/testsuite/gdb.dwarf2/dw2-symtab-includes-lookup.exp [new file with mode: 0644]