This is the mail archive of the gdb@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]

Re: gdb internal error


Andreas Schwab <schwab@suse.de> writes:
> $ cat hello.c
> #include <stdio.h>
> int
> main (void)
> {
>   printf ("Hello, world!\n");
> }
> $ gcc -g3 -DFOO -UFOO -DFOO=2 hello.c -o hello
> $ gdb -ex start hello
> GNU gdb 6.6.90.20070911-cvs
> Copyright (C) 2007 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "ia64-suse-linux"...
> Using host libthread_db library "/lib/libthread_db.so.1".
> /cvs/branch/gdb/gdb/macrotab.c:127: internal-error: macro_bcache_free: Assertion `! t->bcache' failed.
> A problem internal to GDB has been detected,
> further debugging may prove unreliable.
> Quit this debugging session? (y or n) 
>
> The comment in macro_define_object is apparently wrong, especially the
> first sentence in the second paragraph:
>
>   /* If we're redefining a symbol, and the existing key would be
>      identical to our new key, then the splay_tree_insert function
>      will try to delete the old definition.  When the definition is
>      living on an obstack, this isn't a happy thing.
>
>      Since this only happens in the presence of questionable debug
>      info, we just ignore all definitions after the first.  The only
>      case I know of where this arises is in GCC's output for
>      predefined macros, and all the definitions are the same in that
>      case.  */
>
> Andreas.

Hi, Andreas.  Thanks for the bug report.  I've committed the
following, which fixes the problem for me.

gdb/ChangeLog:
2007-09-21  Jim Blandy  <jimb@codesourcery.com>

	* macrotab.h (new_macro_table): Document that removing information
	from an obstack/bcache-managed macro table leaks memory.
	* macrotab.c (macro_free, macro_bcache_free): Instead of asserting
	that data is never freed in obstack/bcache-managed macro tables,
	just leak the storage.
	(macro_undef): If we're undefining a macro at exactly the same
	source location that we defined it, simply remove the definition
	altogether.

diff -r 77afe7ffac2f gdb/macrotab.c
--- a/gdb/macrotab.c	Fri Sep 21 14:38:59 2007 -0700
+++ b/gdb/macrotab.c	Fri Sep 21 17:32:52 2007 -0700
@@ -87,8 +87,14 @@ static void
 static void
 macro_free (void *object, struct macro_table *t)
 {
-  gdb_assert (! t->obstack);
-  xfree (object);
+  if (t->obstack)
+    /* There are cases where we need to remove entries from a macro
+       table, even when reading debugging information.  This should be
+       rare, and there's no easy way to free arbitrary data from an
+       obstack, so we just leak it.  */
+    ;
+  else
+    xfree (object);
 }
 
 
@@ -120,12 +126,18 @@ macro_bcache_str (struct macro_table *t,
 
 
 /* Free a possibly bcached object OBJ.  That is, if the macro table T
-   has a bcache, it's an error; otherwise, xfree OBJ.  */
+   has a bcache, do nothing; otherwise, xfree OBJ.  */
 static void
 macro_bcache_free (struct macro_table *t, void *obj)
 {
-  gdb_assert (! t->bcache);
-  xfree (obj);
+  if (t->bcache)
+    /* There are cases where we need to remove entries from a macro
+       table, even when reading debugging information.  This should be
+       rare, and there's no easy way to free data from a bcache, so we
+       just leak it.  */
+    ;
+  else
+    xfree (obj);
 }
 
 
@@ -781,25 +793,39 @@ macro_undef (struct macro_source_file *s
 
   if (n)
     {
-      /* This function is the only place a macro's end-of-scope
-         location gets set to anything other than "end of the
-         compilation unit" (i.e., end_file is zero).  So if this macro
-         already has its end-of-scope set, then we're probably seeing
-         a second #undefinition for the same #definition.  */
       struct macro_key *key = (struct macro_key *) n->key;
 
-      if (key->end_file)
+      /* If we're removing a definition at exactly the same point that
+         we defined it, then just delete the entry altogether.  GCC
+         4.1.2 will generate DWARF that says to do this if you pass it
+         arguments like '-DFOO -UFOO -DFOO=2'.  */
+      if (source == key->start_file
+          && line == key->start_line)
+        splay_tree_remove (source->table->definitions, n->key);
+
+      else
         {
-	  complaint (&symfile_complaints,
-		     _("macro '%s' is #undefined twice, at %s:%d and %s:%d"), name,
-		     source->filename, line, key->end_file->filename,
-		     key->end_line);
+          /* This function is the only place a macro's end-of-scope
+             location gets set to anything other than "end of the
+             compilation unit" (i.e., end_file is zero).  So if this
+             macro already has its end-of-scope set, then we're
+             probably seeing a second #undefinition for the same
+             #definition.  */
+          if (key->end_file)
+            {
+              complaint (&symfile_complaints,
+                         _("macro '%s' is #undefined twice,"
+                           " at %s:%d and %s:%d"),
+                         name,
+                         source->filename, line,
+                         key->end_file->filename, key->end_line);
+            }
+
+          /* Whether or not we've seen a prior #undefinition, wipe out
+             the old ending point, and make this the ending point.  */
+          key->end_file = source;
+          key->end_line = line;
         }
-
-      /* Whatever the case, wipe out the old ending point, and 
-         make this the ending point.  */
-      key->end_file = source;
-      key->end_line = line;
     }
   else
     {
diff -r 77afe7ffac2f gdb/macrotab.h
--- a/gdb/macrotab.h	Fri Sep 21 14:38:59 2007 -0700
+++ b/gdb/macrotab.h	Fri Sep 21 17:32:52 2007 -0700
@@ -152,15 +152,15 @@ struct macro_source_file
    amongst compilation units in an executable file; if BCACHE is zero,
    don't cache these things.
 
-   Note that, if either OBSTACK or BCACHE are non-zero, then you
-   should only ever add information the macro table --- you should
-   never remove things from it.  You'll get an error if you try.  At
-   the moment, since we only provide obstacks and bcaches for macro
-   tables for symtabs, this restriction makes a nice sanity check.
-   Obstacks and bcaches are pretty much grow-only structures anyway.
-   However, if we find that it's occasionally useful to delete things
-   even from the symtab's tables, and the storage leak isn't a
-   problem, this restriction could be lifted.  */
+   Note that, if either OBSTACK or BCACHE are non-zero, then removing
+   information from the table may leak memory.  Neither obstacks nor
+   bcaches really allow you to remove information, so although we can
+   update the data structure to record the change, we can't free the
+   old data.  At the moment, since we only provide obstacks and
+   bcaches for macro tables for symtabs, this isn't a problem; only
+   odd debugging information makes a definition and then deletes it at
+   the same source location (although 'gcc -DFOO -UFOO -DFOO=2' does
+   do that in GCC 4.1.2.).  */
 struct macro_table *new_macro_table (struct obstack *obstack,
                                      struct bcache *bcache);
 


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