* macrotab.h (new_macro_table): Document that removing information
authorJim Blandy <jimb@codesourcery.com>
Sat, 22 Sep 2007 01:09:19 +0000 (01:09 +0000)
committerJim Blandy <jimb@codesourcery.com>
Sat, 22 Sep 2007 01:09:19 +0000 (01:09 +0000)
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.

gdb/ChangeLog
gdb/macrotab.c
gdb/macrotab.h

index 814fc5e..4e03263 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 2007-09-21  Joel Brobecker  <brobecker@adacore.com>
 
        * symfile.h (struct sym_fns): Add new field sym_read_linetable.
index 65bf8fd..78fa2bb 100644 (file)
@@ -87,8 +87,14 @@ macro_alloc (int size, struct macro_table *t)
 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, const char *s)
 
 
 /* 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 *source, int line,
 
   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);
+            }
 
-      /* Whatever the case, wipe out the old ending point, and 
-         make this the ending point.  */
-      key->end_file = source;
-      key->end_line = 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;
+        }
     }
   else
     {
index c3b686a..de9a545 100644 (file)
@@ -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);