This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch/stabs] Fix for warning: (Internal error: pc 0x4000000 in read in psymtab, but not in symtab.
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 24 Jun 2009 17:28:00 +0100
- Subject: [patch/stabs] Fix for warning: (Internal error: pc 0x4000000 in read in psymtab, but not in symtab.
Hello!
A customer sent us an arm-eabi binary that when loaded into
gdb as:
set $pc = 0x4000000
add-symbol-file foo.elf 0x4000040 -s .rom_vectors 0x4000000
would trigger a bunch of warnings of the form:
warning: (Internal error: pc 0x4000000 in read in psymtab, but not in symtab.)
This was an elf binary with both dwarf and stabs info:
0 .debug_aranges 000024e8 00000000 00000000 0003f748 2**3
CONTENTS, READONLY, DEBUGGING
1 .debug_pubnames 00004bd2 00000000 00000000 00041c30 2**0
CONTENTS, READONLY, DEBUGGING
2 .debug_info 000289ab 00000000 00000000 00046802 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_abbrev 000065ec 00000000 00000000 0006f1ad 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_line 0000c680 00000000 00000000 00075799 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_frame 000069f4 00000000 00000000 00081e1c 2**2
CONTENTS, READONLY, DEBUGGING
6 .debug_str 0000a329 00000000 00000000 00088810 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_loc 0000b4b6 00000000 00000000 00092b39 2**0
CONTENTS, READONLY, DEBUGGING
:
12 .text 00031a24 00008048 00008048 00008048 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
:
19 .stab 000015e4 00000000 00000000 0009eb64 2**2
CONTENTS, READONLY, DEBUGGING
20 .stabstr 000005a9 00000000 00000000 000a0148 2**0
CONTENTS, READONLY, DEBUGGING
21 .debug_ranges 00002470 00000000 00000000 000a06f1 2**0
... and the problem is actually found in the stabs reader.
The problem lies in the stabs psymtab reader, wich sets has_line_number as
soon as it finds N_SLINE, but doesn't reset it when starting a new
psymtab. So subsequent psymtabs coming from the same .stabs section
end up with a stale has_line_number set. Something like this:
dbxread.c:read_dbx_symtab()
{
has_line_numbers = 0;
...
for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
{
...
if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
{
has_line_numbers = 1;
continue;
}
...
add_psymtab ();
...
end_psymtab ();
...
}
If the psymtab ends up empty, GDB usually discards it. But, in the case at
hand, due to a sequence of psymtabs including 'non-empty,line-info' -> 'empty,no-line-info',
the stabs reader ends up thinking it should keep the psymtab, due to
the check below tripping on stale data:
dbxread.c:end_psymtab ()
{
...
if (num_includes == 0
&& number_dependencies == 0
&& pst->n_global_syms == 0
&& pst->n_static_syms == 0
&& has_line_numbers == 0) <<<<<<<<<<<<<<
{
/* Throw away this psymtab, it's empty. We can't deallocate it, since
it is on the obstack, but we can forget to chain it on the list. */
/* Empty psymtabs happen as a result of header files which don't have
any symbols in them. There can be a lot of them. But this check
is wrong, in that a psymtab with N_SLINE entries but nothing else
is not empty, but we don't realize that. Fixing that without slowing
things down might be tricky. */
discard_psymtab (pst);
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *) NULL;
}
}
(It seems that the last two sentences in that second comment are stale too.)
The "assertion" then happens later in find_pc_sect_symtab, where there's
this bit of code:
find_pc_sect_symtab ()
{
<find symtab, and be happy with one, if found>
...
s = NULL;
ps = find_pc_sect_psymtab (pc, section);
if (ps)
{
if (ps->readin)
/* Might want to error() here (in case symtab is corrupt and
will cause a core dump), but maybe we can successfully
continue, so let's not. */
warning (_("\
(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n"),
paddr_nz (pc));
s = PSYMTAB_TO_SYMTAB (ps);
^ ******* S will be NULL here.
}
...
}
There should have been found a symtab for PC, but there wasn't,
so that
internal-error-that's-really-a-warning-who-writes-these-things
warning triggers.
At psymtab_to_symtab time, end_symtab returns NULL, since it ends up
finding no symbols (expected) *and* no line info (unexpected) in the
just built symtab:
if (pending_blocks == NULL
&& file_symbols == NULL
&& global_symbols == NULL
&& have_line_numbers == 0 <<<<<<<<<<<<<
&& pending_macros == NULL)
{
/* Ignore symtabs that have no functions with real debugging
info. */
blockvector = NULL; <<< we reach here.
}
(Note: has_line_numbers != have_line_numbers)
So the right fix, it looks to me, is to clear has_line_numbers
whenever we finish a psymtab, right next to where a couple of
other per-psymtab globals are already cleared. I've checked
that stabs that appears after the empty one (still in the same
.stabs section) do have other N_SLINE entries. The line tables
of unpatched vs patched GDB as output by "maint print symbol" with
-readnow are pretty much identical. I also diffed the output
of "maint info psymtabs" and "maint info symtabs" (with -readnow),
and the only difference is that we do discard a few empty
psymtabs correctly, that weren't discarded before.
In addition, I've tested this patch on arm-none-eabi,
on cygwin (gcc3, still defaulting to stabs), and on x86_64-linux with
make check RUNTESTFLAGS="--target_board=unix/gdb:debug_flags=-gstabs+",
all without regressions. I'm pretty confident this is right, but,
I'm far from a stabs guru or from groking the whole of dbxread.c.
Any comments or hole-pinpointing on my reasoning? Otherwise,
I'll commit it in a few days.
This may or not be PR8863, although the reporter didn't
attach a binary test file to confirm it.
--
Pedro Alves
2009-06-24 Pedro Alves <pedro@codesourcery.com>
* dbxread.c (read_dbx_symtab): Clear has_line_numbers when ending
a psymtab.
---
gdb/dbxread.c | 3 +++
1 file changed, 3 insertions(+)
Index: gdb-stable/gdb/dbxread.c
===================================================================
--- gdb-stable.orig/gdb/dbxread.c 2009-06-22 14:02:28.000000000 -0700
+++ gdb-stable/gdb/dbxread.c 2009-06-23 18:05:48.000000000 -0700
@@ -1382,6 +1382,7 @@ read_dbx_symtab (struct objfile *objfile
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
+ has_line_numbers = 0;
}
else
past_first_source_file = 1;
@@ -1506,6 +1507,7 @@ read_dbx_symtab (struct objfile *objfile
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
+ has_line_numbers = 0;
}
}
@@ -2082,6 +2084,7 @@ pos %d"),
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
+ has_line_numbers = 0;
}
continue;