This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]