This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA/commit] crash while searching for a block's objfile
- From: Joel Brobecker <brobecker at adacore dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 12 Mar 2009 18:48:24 -0700
- Subject: [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);