[gdb/symtab] Fix check-psymtab failure for inline function
authorTom de Vries <tdevries@suse.de>
Tue, 7 Apr 2020 08:57:20 +0000 (10:57 +0200)
committerTom de Vries <tdevries@suse.de>
Tue, 7 Apr 2020 08:57:20 +0000 (10:57 +0200)
Consider test-case inline.c, containing an inline function foo:
...
static inline int foo (void) { return 0; }
int main (void) { return foo (); }
...

And the test-case compiled with -O2 and debug info:
...
$ gcc -g inline.c -O2
...

This results in a DWARF entry for foo without pc info:
...
<1><114>: Abbrev Number: 4 (DW_TAG_subprogram)
   <115>   DW_AT_name        : foo
   <119>   DW_AT_decl_file   : 1
   <11a>   DW_AT_decl_line   : 2
   <11b>   DW_AT_prototyped  : 1
   <11b>   DW_AT_type        : <0x10d>
   <11f>   DW_AT_inline      : 3       (declared as inline and inlined)
...

When loading the executable in gdb, we create a partial symbol for foo, but
after expansion into a full symbol table no actual symbol is created,
resulting in a maint check-psymtab failure:
...
(gdb) maint check-psymtab
Static symbol `foo' only found in inline.c psymtab
...

Fix this by skipping this type of partial symbol during the check.

Note that we're not fixing this by not creating the partial symbol, because
this breaks setting a breakpoint on an inlined inline function in a CU for
which the partial symtab has not been expanded (test-case
gdb.dwarf2/break-inline-psymtab.exp).

Tested on x86_64-linux.

gdb/ChangeLog:

2020-04-07  Tom de Vries  <tdevries@suse.de>

* psymtab.c (maintenance_check_psymtabs): Skip static LOC_BLOCK
symbols without address.

gdb/testsuite/ChangeLog:

2020-04-07  Tom de Vries  <tdevries@suse.de>

* gdb.base/check-psymtab.c: New test.
* gdb.base/check-psymtab.exp: New file.

gdb/ChangeLog
gdb/psymtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/check-psymtab.c [new file with mode: 0644]
gdb/testsuite/gdb.base/check-psymtab.exp [new file with mode: 0644]

index bd1a0f4df18e8ea8e424efc33790ee3dfbb76ee6..16a0089872242cfb41df92a7b2d10b5c02c538f7 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-07  Tom de Vries  <tdevries@suse.de>
+
+       * psymtab.c (maintenance_check_psymtabs): Skip static LOC_BLOCK
+       symbols without address.
+
 2020-04-06  Kamil Rytarowski  <n54@gmx.com>
 
        * nbsd-nat.h (struct thread_info): Add forward declaration.
index 129eecb067119291bd98aea86355831d8ab13867..44d4978d5394552da01c4167e192c7fd3eefe13c 100644 (file)
@@ -2113,7 +2113,7 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
   struct compunit_symtab *cust = NULL;
   const struct blockvector *bv;
   const struct block *b;
-  int length;
+  int i;
 
   for (objfile *objfile : current_program_space->objfiles ())
     for (partial_symtab *ps : require_partial_symbols (objfile, true))
@@ -2147,9 +2147,14 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
        b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
        partial_symbol **psym
          = &objfile->partial_symtabs->static_psymbols[ps->statics_offset];
-       length = ps->n_static_syms;
-       while (length--)
+       for (i = 0; i < ps->n_static_syms; psym++, i++)
          {
+           /* Skip symbols for inlined functions without address.  These may
+              or may not have a match in the full symtab.  */
+           if ((*psym)->aclass == LOC_BLOCK
+               && (*psym)->ginfo.value.address == 0)
+             continue;
+
            sym = block_lookup_symbol (b, (*psym)->ginfo.search_name (),
                                       symbol_name_match_type::SEARCH_NAME,
                                       (*psym)->domain);
@@ -2161,12 +2166,10 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
                puts_filtered (ps->filename);
                printf_filtered (" psymtab\n");
              }
-           psym++;
          }
        b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
        psym = &objfile->partial_symtabs->global_psymbols[ps->globals_offset];
-       length = ps->n_global_syms;
-       while (length--)
+       for (i = 0; i < ps->n_global_syms; psym++, i++)
          {
            sym = block_lookup_symbol (b, (*psym)->ginfo.search_name (),
                                       symbol_name_match_type::SEARCH_NAME,
@@ -2179,7 +2182,6 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
                puts_filtered (ps->filename);
                printf_filtered (" psymtab\n");
              }
-           psym++;
          }
        if (ps->raw_text_high () != 0
            && (ps->text_low (objfile) < BLOCK_START (b)
index 87015932ed7f3c6252eb4d6769b2d25937b0daac..bd55a78b211296c8f2fbdbd2e2cdd348e59616ec 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-07  Tom de Vries  <tdevries@suse.de>
+
+       * gdb.base/check-psymtab.c: New test.
+       * gdb.base/check-psymtab.exp: New file.
+
 2020-04-06  Tom Tromey  <tromey@adacore.com>
 
        * gdb.ada/variant-record/proc.adb: New file.
diff --git a/gdb/testsuite/gdb.base/check-psymtab.c b/gdb/testsuite/gdb.base/check-psymtab.c
new file mode 100644 (file)
index 0000000..01c4fc8
--- /dev/null
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020 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/>.  */
+
+static inline int __attribute__((__always_inline__))
+foo (void)
+{
+  return 0;
+}
+
+int
+main (void)
+{
+  return foo ();
+}
diff --git a/gdb/testsuite/gdb.base/check-psymtab.exp b/gdb/testsuite/gdb.base/check-psymtab.exp
new file mode 100644 (file)
index 0000000..e9d40f3
--- /dev/null
@@ -0,0 +1,26 @@
+# Copyright 2020 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/>.  */
+
+standard_testfile
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} {
+    return -1
+}
+
+gdb_test_no_output "maint expand-symtabs"
+
+# Check that we don't get:
+#   Static symbol `foo' only found in check-psymtab.c psymtab
+gdb_test_no_output "maint check-psymtab"