[gdb/symtab] Fix assert in write_one_signatured_type
authorTom de Vries <tdevries@suse.de>
Tue, 2 Feb 2021 07:37:45 +0000 (08:37 +0100)
committerTom de Vries <tdevries@suse.de>
Tue, 2 Feb 2021 07:37:45 +0000 (08:37 +0100)
When running test-case gdb.dwarf2/fission-reread.exp with target board
cc-with-gdb-index, we run into an abort during the generation of the gdb-index
by cc-with-tweaks.sh:
...
build/gdb/testsuite/cache/gdb.sh: line 1: 27275 Aborted  (core dumped)
...

This can be reproduced on the command line like this:
...
$ gdb -batch ./outputs/gdb.dwarf2/fission-reread/fission-reread \
  -ex 'save gdb-index  ./outputs/gdb.dwarf2/fission-reread'
warning: Could not find DWO TU fission-reread.dwo(0x9022f1ceac7e8b19) \
  referenced by TU at offset 0x0 [in module fission-reread]
warning: Could not find DWO CU fission-reread.dwo(0x807060504030201) \
  referenced by CU at offset 0x561 [in module fission-reread]
Aborted (core dumped)
...

The abort is a segfault due to a using a nullptr psymtab in
write_one_signatured_type.

The problem is that we're trying to write index entries for the type unit
with signature:
...
(gdb) p /x entry->signature
$2 = 0x9022f1ceac7e8b19
...
which is a skeleton type unit:
...
Contents of the .debug_types section:

  Compilation Unit @ offset 0x0:
   Length:        0x4a (32-bit)
   Version:       4
   Abbrev Offset: 0x165
   Pointer Size:  4
   Signature:     0x9022f1ceac7e8b19
   Type Offset:   0x0
 <0><17>: Abbrev Number: 2 (DW_TAG_type_unit)
    <18>   DW_AT_comp_dir    : /tmp/src/gdb/testsuite
    <2f>   DW_AT_GNU_dwo_name: fission-reread.dwo
    <42>   DW_AT_GNU_pubnames: 0x0
    <46>   DW_AT_GNU_pubtypes: 0x0
    <4a>   DW_AT_GNU_addr_base: 0x0
...
referring to a .dwo file, but as the warnings show, the .dwo file is not
found.

Fix this by skipping the type unit in write_one_signatured_type if
psymtab == nullptr.

Tested on x86_64-linux.

gdb/ChangeLog:

2021-02-02  Tom de Vries  <tdevries@suse.de>

PR symtab/24620
* dwarf2/index-write.c (write_one_signatured_type): Skip if
psymtab == nullptr.

gdb/testsuite/ChangeLog:

2021-02-02  Tom de Vries  <tdevries@suse.de>

PR symtab/24620
* gdb.dwarf2/fission-reread.exp: Add test-case.

gdb/ChangeLog
gdb/dwarf2/index-write.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/fission-reread.exp

index 7323a13e0f279b7f7e803274ccf122135145e463..0592c8643d6e88257d37b342f6a79a034cea0381 100644 (file)
@@ -1,3 +1,9 @@
+2021-02-02  Tom de Vries  <tdevries@suse.de>
+
+       PR symtab/24620
+       * dwarf2/index-write.c (write_one_signatured_type): Skip if
+       psymtab == nullptr.
+
 2021-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * Makefile.in (HFILES_NO_SRCDIR): Add corefile.h.
index 66781feaf468f73127d81d3a443a2841a6e710d1..a7b9ae66cae26212a6f564c3659b70fa4ad37f84 100644 (file)
@@ -616,6 +616,14 @@ write_one_signatured_type (void **slot, void *d)
   struct signatured_type *entry = (struct signatured_type *) *slot;
   partial_symtab *psymtab = entry->per_cu.v.psymtab;
 
+  if (psymtab == nullptr)
+    {
+      /* We can end up here when processing a skeleton CU referring to a
+        .dwo file that hasn't been found.  There's not much we can do in
+        such a case, so skip this CU.  */
+      return 1;
+    }
+
   write_psymbols (info->symtab, info->psyms_seen,
                  psymtab->global_psymbols, info->cu_index,
                  0);
index a557765c4b6c2d800f5d045623d9c808d6e121a1..0f3f445b8f25ef9321a9e528bba2ed4513e6734b 100644 (file)
@@ -1,3 +1,8 @@
+2021-02-02  Tom de Vries  <tdevries@suse.de>
+
+       PR symtab/24620
+       * gdb.dwarf2/fission-reread.exp: Add test-case.
+
 2021-02-01  Tom de Vries  <tdevries@suse.de>
 
        * gdb.dwarf2/fission-base.S: Pass -DDWO=$dwo.
index b97c48ad1b36733ef89cf6c0cd9adedc9514aff7..58132794ee7a98a8bf5be16ac43126602e1f4afa 100644 (file)
@@ -56,3 +56,18 @@ pass $testfile
 gdb_unload
 # If we get this far gdb didn't crash, nor did an error occur.
 pass "$testfile - unload"
+
+# Test-case for PR24620: Delete the .dwo file and verify that
+# save gdb-index doesn't crash.
+remote_file target delete $dwo
+clean_restart $binfile
+set output_dir [standard_output_file ""]
+set cmd "save gdb-index"
+gdb_test_multiple "$cmd $output_dir" $cmd {
+    -re -wrap "Cannot use an index to create the index.*" {
+       unsupported $gdb_test_name
+    }
+    -re "^$cmd \[^\r\n\]*\r\n$gdb_prompt $" {
+       pass $gdb_test_name
+    }
+}