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]

[RFA/commit] crash while searching for a block's objfile


We noticed this problem on ia64-linux, but this is not specific
to the target. It's just that the compiler produced a unit that
contains very little debugging information.

I cannot provide the sources to reproduce the problem, but the issue
looks like this:

        (gdb) p the_item.Item_Type
        zsh: 9170 segmentation fault  gdb dyn_ref1_main

I wrote a description of the problem:

OK - It took me a little while to get the whole picture, but I think
I get it now. Here is a summary:

The "print" command fails while trying to find the symtab associated
to a block.  For that, we call lookup_objfile_from_block () which
fails at the following line:

1361        if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))

And when I inspect our symtab ("s"), I find that there is no blockvector
(ie s->blockvector is NULL)!!! "s" is a symtab for system.ads and has
nothing set.

Following that trail, I was able to find that this symtab was created
while processing the includes in the line table of file simp_generic.adb
(which is a generic package). Looking at the debug information generated
for this file, we see that the .debug_info contains one compile-unit
with only one child,  a strange structure-type:

 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
     DW_AT_producer    : (indirect string, offset: 0x0): GNU Ada 4.3.3 20090114
+for GNAT Pro 6.3.0w (20090114) -gdwarf+-
     DW_AT_language    : 13     (ADA 95)
     DW_AT_name        : (indirect string, offset: 0x40): simp_generic.adb
     DW_AT_comp_dir    : (indirect string, offset: 0x51): [...]
     DW_AT_low_pc      : 0 0
     DW_AT_high_pc     : 0 0
     DW_AT_stmt_list   : 0
 <1><2d>: Abbrev Number: 2 (DW_TAG_structure_type)
     DW_AT_byte_size   : 16
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 1

The DW_TAG_structure_type die ends up being ignored, because it doesn't
have a name (we created a type for it, but we didn't create an
associated symbol).

Parallel to that, also of interest is the fact that the unit has
a line table (DW_AT_stmt_list). That line table actually has no
lines in it, but it does tell us that our unit includes system.ads:

     The File Name Table:
      Entry Dir     Time    Size    Name
      1     1       0       0       system.ads

It is while processing that entry that we create an incomplete
symtab for this include:

      /* Make sure a symtab is created for every file, even files
         which contain only variables (i.e. no code with associated
         line numbers).  */
      [...]
          if (current_subfile->symtab == NULL)
            current_subfile->symtab = allocate_symtab (current_subfile->name,
                                                       cu->objfile);
          fe->symtab = current_subfile->symtab;

After some researching, I think we do that because of DIEs that
refer to that file via DW_AT_decl_file attribute - we want to be
able to ask the debugger were a type was defined, and GDB answers
by storing a reference to the symtab inside the type/variable symbol.

The problems start when GDB decides to ignore our DW_TAG_structure_type
DIE, as explained above.  As a result, we determine that our compile
unit is completely empty (no lines of code, no symbols, no macros,
etc), and thus decides to ignore all the includes. See end_symtab
in buildsym.c:

  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;

This causes GDB to leave some symtabs these symtabs we created earlier
as partially uninitialized.

The fix I implemented consisted in "unlinking" a symtab if it is "empty".
We cannot actually free its associated memory because the symtab was
allocated on an obstack.

2009-03-12  Joel Brobecker  <brobecker@adacore.com>

	* buildsym.c (end_symtab): If we ignore the subfiles, then
	unlink the associated symtabs if they were already allocated.

Tested on amd64-linux. This also passed AdaCore's regression testsuite
on all the targets we have here.

I'd love some feedback on this patch, if you think there is a better
way of doing this. Otherwise, I'd like to commit this patch sometime
next week.

Thanks,
-- 
Joel
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 55ace15..6de817f 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -1118,6 +1118,32 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 
 	  symtab->primary = 0;
 	}
+      else
+        {
+          if (subfile->symtab)
+            {
+              /* Since we are ignoring that subfile, we also need
+                 to unlink the associated empty symtab that we created.
+                 Otherwise, we can into trouble because various parts
+                 such as the block-vector are uninitialized whereas
+                 the rest of the code assumes that they are.
+                 
+                 We can only unlink the symtab because it was allocated
+                 on the objfile obstack.  */
+              struct symtab *s;
+
+              if (objfile->symtabs == subfile->symtab)
+                objfile->symtabs = objfile->symtabs->next;
+              else
+                ALL_OBJFILE_SYMTABS (objfile, s)
+                  if (s->next == subfile->symtab)
+                    {
+                      s->next = s->next->next;
+                      break;
+                    }
+              subfile->symtab = NULL;
+            }
+        }
       if (subfile->name != NULL)
 	{
 	  xfree ((void *) subfile->name);

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