m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: 20-gary-unrevert-memory-handling-bits-of-15-gary-cleanup-from-renam


From: Gary V. Vaughan
Subject: FYI: 20-gary-unrevert-memory-handling-bits-of-15-gary-cleanup-from-renaming-token-data-to-symbol.patch
Date: Sun, 30 Sep 2001 23:34:12 +0100
User-agent: Mutt/1.3.22.1i

Index: ChangeLog
from  Gary V. Vaughan  <address@hidden>
        Reinstate the memory handling improvements from the patch I just
        reverted.  Relevant ChangeLog entries repeated here:

        * m4/module.c (m4_module_remove): New function that holds the core
        of the old m4_module_unload.
        (m4_module_unload): Use it.
        (m4_module_unload_all): When we know the modules will never be
        used again (i.e. on exit), free up as much module memory as
        possible.  There are still some artifacts from resident modules
        living inside ltdl.c, but everything else is freed.
        * m4/debug.c (m4_debug_exit): Free memory allocated in
        m4_debug_init().
        * m4/input.c (m4_input_exit): Ditto wrt m4_input_init().
        * m4/output.c (m4_output_exit): Ditto wrt m4_output_init ().
        * src/stackovf.c (stackovf_exit): Ditto wrt setup_stackovf_trap ().
        * m4/m4module.h: Updated prototypes.
        * m4/hash.c (m4_hash_exit): Free the nodes on the free list.
        * m4/hash.h: Updated prototypes.
        * src/main.c (main): Use all these new functions to clean up as
        much memory as possible before exit.

Index: m4/debug.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/debug.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 debug.c
--- m4/debug.c 2001/09/30 14:43:38 1.7
+++ m4/debug.c 2001/09/30 22:24:09
@@ -44,6 +44,12 @@ m4_debug_init (void)
   obstack_init (&trace);
 }
 
+void
+m4_debug_exit (void)
+{
+  obstack_free (&trace, NULL);
+}
+
 
 
 /* Function to decode the debugging flags OPTS.  Used by main while
Index: m4/hash.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/hash.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 hash.c
--- m4/hash.c 2001/09/30 14:43:38 1.4
+++ m4/hash.c 2001/09/30 22:24:10
@@ -271,8 +271,9 @@ m4_hash_remove (m4_hash *hash, const voi
 
 /* Return the address of the value field of the first node in
    HASH that has a matching KEY.  The address is returned so that
-   an explicit 0 value can be distinguihed from a failed lookup
-   (also 0).  */
+   an explicit 0 value can be distinguished from a failed lookup
+   (also 0).  Fortuitously for M4, this also means that the value
+   field can be changed `in situ' to implement a value stack.  */
 void **
 m4_hash_lookup (m4_hash *hash, const void *key)
 {
@@ -363,6 +364,17 @@ m4_hash_bucket_insert (m4_hash *hash, m4
   while (bucket);
 }
 
+void
+m4_hash_exit (void)
+{
+  while (m4_hash_node_free_list)
+    {
+      m4_hash_node *stale = m4_hash_node_free_list;
+      m4_hash_node_free_list = M4_HASH_NODE_NEXT (stale);
+      xfree (stale);
+    }
+}
+ 
 
 
 struct m4_hash_iterator
Index: m4/hash.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/hash.h,v
retrieving revision 1.3
diff -u -p -u -r1.3 hash.h
--- m4/hash.h 2001/09/30 14:43:38 1.3
+++ m4/hash.h 2001/09/30 22:24:10
@@ -44,6 +44,7 @@ void          m4_hash_insert  (m4_hash *hash, con
 void *         m4_hash_remove  (m4_hash *hash, const void *key);
 void **                m4_hash_lookup  (m4_hash *hash, const void *key);
 size_t         m4_hash_length  (m4_hash *hash);
+void           m4_hash_exit    (void);
 
 
 
Index: m4/input.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/input.c,v
retrieving revision 1.12
diff -u -p -u -r1.12 input.c
--- m4/input.c 2001/09/30 14:43:38 1.12
+++ m4/input.c 2001/09/30 22:24:13
@@ -793,6 +793,18 @@ m4_input_init (void)
   use_macro_escape = FALSE;
 }
 
+ void
+m4_input_exit (void)
+{
+  XFREE (lquote.string);
+  XFREE (rquote.string);
+  XFREE (bcomm.string);
+  XFREE (ecomm.string);
+  obstack_free (&wrapup_stack, NULL);
+  obstack_free (&input_stack, NULL);
+  obstack_free (&token_stack, NULL);
+}
+
 void
 m4_syntax_init (void)
 {
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.31
diff -u -p -u -r1.31 m4module.h
--- m4/m4module.h 2001/09/30 14:43:38 1.31
+++ m4/m4module.h 2001/09/30 22:24:14
@@ -94,6 +94,7 @@ extern m4_hash *m4_symtab;
 extern void    m4_symtab_init          (void);
 extern int     m4_symtab_apply         (m4_symtab_apply_func *, void *);
 extern void    m4_symtab_remove_module_references (lt_dlhandle);
+extern void    m4_symtab_exit          (void);
 
 extern m4_symbol *m4_symbol_lookup     (const char *);
 extern m4_symbol *m4_symbol_pushdef    (const char *);
@@ -291,6 +292,7 @@ FILE *m4_debug;
   while (0)
 
 void m4_debug_init (void);
+void m4_debug_exit (void);
 int m4_debug_decode (const char *);
 void m4_debug_flush_files (void);
 boolean m4_debug_set_output (const char *);
@@ -375,6 +377,7 @@ int m4_current_line;
 
 extern int     m4_syntax_code  (char ch);
 extern void    m4_input_init   (void);
+extern void    m4_input_exit   (void);
 extern void    m4_syntax_init  (void);
 extern int     m4_peek_input   (void);
 extern m4_token_t m4_next_token (m4_token_data *);
@@ -399,6 +402,7 @@ int m4_current_diversion;
 int m4_output_current_line;
 
 extern void    m4_output_init  (void);
+extern void    m4_output_exit  (void);
 extern void    m4_shipout_text (struct obstack *, const char *, int);
 extern void    m4_make_diversion (int);
 extern void    m4_insert_diversion (int);
Index: m4/m4private.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4private.h,v
retrieving revision 1.11
diff -u -p -u -r1.11 m4private.h
--- m4/m4private.h 2001/09/30 14:43:38 1.11
+++ m4/m4private.h 2001/09/30 22:24:14
@@ -79,9 +79,14 @@ struct m4_symbol
 /* Debugging the memory allocator.  */
 
 #if WITH_DMALLOC
-# define DMALLOC_FUNC_CHECK
-# include <dmalloc.h>
-#endif
+#  define DMALLOC_FUNC_CHECK
+#  include <dmalloc.h>
+
+/* Dmalloc expects us to use a void returning xfree.  */
+#  undef XFREE
+#  define XFREE(p)     if (p) xfree (p)
+
+#endif /* WITH_DMALLOC */
 
 /* Other debug stuff.  */
 
Index: m4/module.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/module.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 module.c
--- m4/module.c 2001/09/30 14:43:38 1.13
+++ m4/module.c 2001/09/30 22:24:17
@@ -83,6 +83,8 @@
 #define M4_FINISH_SYMBOL       "m4_finish_module"
 
 static const char*  m4_module_dlerror  (void);
+static int         m4_module_remove    (lt_dlhandle handle,
+                                        struct obstack *obs);
 
 static lt_dlcaller_id m4_caller_id = 0;
 
@@ -177,9 +179,11 @@ m4_module_init (void)
       return;
     }
 
+#if !WITH_DMALLOC
   /* initialise libltdl's memory management. */
   lt_dlmalloc = xmalloc;
   lt_dlfree   = (void (*)(void*)) xfree;
+#endif
 
   errors      = lt_dlinit ();
 
@@ -323,11 +327,11 @@ void
 m4_module_close (lt_dlhandle handle, struct obstack *obs)
 {
   m4_module_finish_func *finish_func   = 0;
-  const char           *name           = 0;
+  char                 *name           = 0;
   int                   errors         = 0;
-  
+
   assert (handle);
-  name = m4_module_name (handle);
+  name = xstrdup (m4_module_name (handle));
 
   /* Run any finishing function for the opened module. */
   finish_func = (m4_module_finish_func *) lt_dlsym (handle, M4_FINISH_SYMBOL);
@@ -343,18 +347,16 @@ m4_module_close (lt_dlhandle handle, str
       
   if (!lt_dlisresident (handle))
     {
-      {
-       const lt_dlinfo  *info  = lt_dlgetinfo (handle);
+      const lt_dlinfo  *info   = lt_dlgetinfo (handle);
 
-       /* When we are about to unload the module for the final
-          time, be sure to release any client data memory.  */
-       if (info && (info->ref_count == 1))
-         {
-           m4_module_data *stale
-             = lt_dlcaller_set_data (m4_caller_id, handle, 0);
-           xfree (stale);
-         }
-      }
+      /* When we are about to unload the module for the final
+        time, be sure to release any client data memory.  */
+      if (info && (info->ref_count == 1))
+       {
+         m4_module_data *stale
+           = lt_dlcaller_set_data (m4_caller_id, handle, 0);
+         XFREE (stale);
+       }
 
       errors = lt_dlclose (handle);
       if (!errors)
@@ -364,6 +366,10 @@ m4_module_close (lt_dlhandle handle, str
 #endif /* DEBUG_MODULES */
        }
     }
+#ifdef DEBUG_MODULES
+  else
+    M4_DEBUG_MESSAGE1("module %s: resident module not closed", name);
+#endif /* DEBUG_MODULES */
 
   if (errors)
     {
@@ -371,6 +377,8 @@ m4_module_close (lt_dlhandle handle, str
                _("ERROR: cannot close module `%s': %s"),
                name, m4_module_dlerror ()));
     }
+  
+  xfree (name);
 }
 
 void
@@ -384,6 +392,10 @@ m4_module_close_all (struct obstack *obs
         closed, even to find the address of the next handle.  */
       lt_dlhandle pending = handle;
       handle = lt_dlhandle_next (handle);
+#ifdef DEBUG_MODULES
+      M4_DEBUG_MESSAGE1("module %s: attempting module close",
+                       m4_module_name (pending));
+#endif /* DEBUG_MODULES */
       m4_module_close (pending, obs);
     }
 
@@ -438,6 +450,46 @@ m4_module_load (const char *name, struct
   return handle;
 }
 
+int
+m4_module_remove (lt_dlhandle handle, struct obstack *obs)
+{
+  const lt_dlinfo *info                = 0;
+  int             errors       = 0;
+
+  assert (handle);
+
+  info = lt_dlgetinfo (handle);
+
+  /* Only do the actual close when the number of calls to close this
+     module is equal to the number of times it was opened. */
+#ifdef DEBUG_MODULES
+  if (info->ref_count > 1)
+    {
+      M4_DEBUG_MESSAGE2("module %s: now has %d references.",
+                       m4_module_name (handle), info->ref_count -1);
+    }
+#endif /* DEBUG_MODULES */
+
+  if (info->ref_count == 1)
+    {
+      /* Remove the table references only when ref_count is *exactly*
+        equal to 1.  If m4_module_close is called again on a
+        resident module after the references have already been
+        removed, we needn't try to remove them again!  */
+      m4_symtab_remove_module_references (handle);
+
+#ifdef DEBUG_MODULES
+      M4_DEBUG_MESSAGE1("module %s: symbols unloaded",
+                       m4_module_name (handle));
+#endif /* DEBUG_MODULES */
+    }
+
+  if (!errors)
+    m4_module_close (handle, obs);
+
+  return errors;
+}
+
 /* Unload a module.  */
 void
 m4_module_unload (const char *name, struct obstack *obs)
@@ -460,40 +512,51 @@ m4_module_unload (const char *name, stru
       ++errors;
     }
   else
+    errors = m4_module_remove (handle, obs);
+
+  if (errors)
     {
-      const lt_dlinfo *info = lt_dlgetinfo (handle);
+      M4ERROR ((EXIT_FAILURE, 0,
+               _("ERROR: cannot unload module `%s': %s"),
+               name, m4_module_dlerror ()));
+    }
+}
+
+void
+m4_module_unload_all (void)
+{
+  lt_dlhandle  handle  = lt_dlhandle_next (0);
+  int          errors  = 0;
+
+  while (handle && !errors)
+    {
+      lt_dlhandle      pending = handle;
+      const lt_dlinfo *info    = lt_dlgetinfo (pending);
 
-      /* Only do the actual close when the number of calls to close this
-        module is equal to the number of times it was opened. */
-      if (info->ref_count > 1)
+      /* We are *really* shutting down here, so freeing the module
+        data is required.  */
+      if (info)
        {
-#ifdef DEBUG_MODULES
-         M4_DEBUG_MESSAGE2("module %s: now has %d references.",
-                           name, info->ref_count -1);
-#endif /* DEBUG_MODULES */
+         m4_module_data *stale
+           = lt_dlcaller_set_data (m4_caller_id, handle, 0);
+         XFREE (stale);
        }
 
-      if (info->ref_count == 1)
-       {
-         /* Remove the table references only when ref_count is *exactly*
-            equal to 1.  If m4_module_close is called again on a
-            resident module after the references have already been
-            removed, we needn't try to remove them again!  */
-         m4_symtab_remove_module_references (handle);
+      /* If we are about to unload the final reference, move on to the
+        next handle before we unload the current one.  */
+      if (info->ref_count <= 1)
+       handle = lt_dlhandle_next (pending);
 
-#ifdef DEBUG_MODULES
-         M4_DEBUG_MESSAGE1("module %s: symbols unloaded", name);
-#endif /* DEBUG_MODULES */
-       }
+      errors = m4_module_remove (pending, 0);
     }
 
   if (!errors)
-    m4_module_close (handle, obs);
+    errors = lt_dlexit();
 
   if (errors)
     {
       M4ERROR ((EXIT_FAILURE, 0,
-               _("ERROR: cannot unload module `%s': %s"),
-               name, m4_module_dlerror ()));
+               _("ERROR: cannot unload all modules: %s"),
+               m4_module_dlerror ()));
     }
 }
Index: m4/output.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/output.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 output.c
--- m4/output.c 2001/09/30 14:43:38 1.7
+++ m4/output.c 2001/09/30 22:24:19
@@ -105,7 +105,7 @@ int m4_output_current_line;
 void
 m4_output_init (void)
 {
-  diversion_table = (struct diversion *) xmalloc (sizeof (struct diversion));
+  diversion_table = XMALLOC (struct diversion, 1);
   diversions = 1;
   diversion_table[0].file = stdout;
   diversion_table[0].buffer = NULL;
@@ -120,6 +120,14 @@ m4_output_init (void)
   output_unused = 0;
 }
 
+void
+m4_output_exit (void)
+{
+  assert (diversions = 1);
+  XFREE (diversion_table);
+}
+
+
 #ifdef HAVE_MKTEMP
 #ifndef HAVE_MKSTEMP
 
@@ -683,4 +691,3 @@ m4_freeze_diversions (file)
   if (saved_number != last_inserted)
     fprintf (file, "D%d,0\n\n", saved_number);
 }
-
Index: m4/symtab.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/symtab.c,v
retrieving revision 1.23
diff -u -p -u -r1.23 symtab.c
--- m4/symtab.c 2001/09/30 14:43:38 1.23
+++ m4/symtab.c 2001/09/30 22:24:19
@@ -18,6 +18,11 @@
    02111-1307  USA
 */
 
+#include "m4private.h"
+
+#define DEBUG_SYM              /* Define this to see runtime debug info.  */
+#undef DEBUG_SYM
+
 /* This file handles all the low level work around the symbol table.  The
    symbol table is an abstract hash table type implemented in hash.c.  Each
    symbol is represented by `struct m4_symbol', which is stored in the hash
@@ -27,13 +32,13 @@
    simply ordered on the stack by age.  The most recently pushed definition
    will then always be the first found.  */
 
-#include "m4private.h"
-
 static size_t  m4_symtab_hash          (const void *key);
 static int     m4_symtab_cmp           (const void *key, const void *try);
 static void    m4_token_data_delete    (m4_token_data *data);
 static void    m4_symbol_pop           (m4_symbol *symbol);
 static void    m4_symbol_del           (m4_symbol *symbol);
+static int     m4_symbol_destroy       (const char *name, m4_symbol *symbol,
+                                        void *data);
 
 
 /* Pointer to symbol table.  */
@@ -47,8 +52,23 @@ m4_symtab_init (void)
   m4_symtab = m4_hash_new (m4_symtab_hash, m4_symtab_cmp);
 }
 
+int
+m4_symbol_destroy (const char *name, m4_symbol *symbol, void *data)
+{
+  m4_symbol_delete (name);
+  return 0;
+}
+
+void
+m4_symtab_exit (void)
+{
+  m4_symtab_apply (m4_symbol_destroy, NULL);
+  m4_hash_delete (m4_symtab);
+  m4_hash_exit ();
+}
+
 /* Return a hashvalue for a string, from GNU-emacs.  */
-size_t
+static size_t
 m4_symtab_hash (const void *key)
 {
   int val = 0;
@@ -65,7 +85,7 @@ m4_symtab_hash (const void *key)
   return val;
 }
 
-int
+static int
 m4_symtab_cmp (const void *key, const void *try)
 {
   return (strcmp ((const char *) key, (const char *) try));
@@ -73,7 +93,7 @@ m4_symtab_cmp (const void *key, const vo
 
 
 
-void
+static void
 m4_token_data_delete (m4_token_data *data)
 {
   assert (data);
@@ -167,11 +187,11 @@ m4_symbol_pushdef (const char *name)
 m4_symbol *
 m4_symbol_define (const char *name)
 {
-  m4_symbol *res = m4_symbol_lookup (name);
-  if (res)
-    return res;
+  m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);
+  if (psymbol)
+    return *psymbol;
   else
-    m4_symbol_pushdef (name);
+    return m4_symbol_pushdef (name);
 }
 
 
@@ -200,6 +220,11 @@ m4_symbol_delete (const char *name)
   m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);
 
   assert (psymbol);
+
+#ifdef DEBUG_SYM
+  M4_DEBUG_MESSAGE1("symbol %s recycled.", name);
+#endif
+
   xfree (m4_hash_remove (m4_symtab, name));
   m4_symbol_del (*psymbol);
 }
@@ -253,6 +278,7 @@ m4_symtab_remove_module_references (lt_d
 
   assert (handle);
 
+   /* Traverse each symbol name in the hash table.  */
   while ((place = m4_hash_iterator_next (m4_symtab, place)))
     {
       m4_symbol *symbol = (m4_symbol *) m4_hash_iterator_value (place);
@@ -286,9 +312,9 @@ m4_symtab_remove_module_references (lt_d
     }
 }
 
-/* The following function is used for the cases, where we want to do
+/* The following function is used for the cases where we want to do
    something to each and every symbol in the table.  The function
-   hack_all_symbols () traverses the symbol table, and calls a specified
+   m4_symtab_apply () traverses the symbol table, and calls a specified
    function FUNC for each symbol in the table.  FUNC is called with a
    pointer to the symbol, and the DATA argument.  */
 int
@@ -327,7 +353,7 @@ symtab_debug (void)
   m4_symbol *s;
   int delete;
 
-  while ((t = m4_next_token (&td)) != NULL)
+  while ((t = m4_next_token (&td)) != M4_TOKEN_EOF)
     {
       if (t != M4_TOKEN_WORD)
        continue;
Index: src/freeze.c
===================================================================
RCS file: /cvsroot/m4/m4/src/freeze.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 freeze.c
--- src/freeze.c 2001/09/30 14:43:38 1.18
+++ src/freeze.c 2001/09/30 22:24:21
@@ -128,7 +128,7 @@ produce_symbol_dump (FILE *file, m4_hash
 
   while ((place = m4_hash_iterator_next (hash, place)))
     {
-      const char   *symbol_name        = m4_hash_iterator_key (place);
+      const char   *symbol_name        = (const char *) m4_hash_iterator_key 
(place);
       m4_symbol           *symbol      = m4_hash_iterator_value (place);
       lt_dlhandle   handle     = M4_SYMBOL_HANDLE (symbol);
       const char   *module_name        = handle ? m4_module_name (handle) : 
NULL;
Index: src/m4.h
===================================================================
RCS file: /cvsroot/m4/m4/src/m4.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 m4.h
--- src/m4.h 2001/09/30 14:43:38 1.10
+++ src/m4.h 2001/09/30 22:24:21
@@ -99,6 +99,7 @@ char *mktemp ();
 #ifdef USE_STACKOVF
 void setup_stackovf_trap (char *const *, char *const *,
                          void (*handler) (void));
+void stackovf_exit (void);
 #endif
 
 
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.26
diff -u -p -u -r1.26 main.c
--- src/main.c 2001/09/30 14:43:38 1.26
+++ src/main.c 2001/09/30 22:24:22
@@ -516,10 +516,21 @@ warranty; not even for MERCHANTABILITY o
       m4_undivert_all ();
     }
 
-  {
-    struct obstack *obs = 0;
-    m4_module_close_all (obs);
-  }
+  m4_module_unload_all ();
+
+  /* The remaining cleanup functions systematically free all of the
+     memory we still have pointers to.  By definition, if there is
+     anything left when we're done: it was caused by a memory leak.
+     Strictly, we don't need to do this, but it makes leak detection
+     a whole lot easier!  */
+  m4_symtab_exit ();
+  m4_output_exit ();
+  m4_input_exit ();
+  m4_debug_exit ();
+
+#ifdef USE_STACKOVF
+  stackovf_exit ();
+#endif
 
   exit (exit_status);
 }
Index: src/stackovf.c
===================================================================
RCS file: /cvsroot/m4/m4/src/stackovf.c,v
retrieving revision 1.8
diff -u -p -u -r1.8 stackovf.c
--- src/stackovf.c 2001/09/30 14:43:38 1.8
+++ src/stackovf.c 2001/09/30 22:24:23
@@ -118,6 +118,7 @@ extern int  sigstack        (struct sigstack *, 
 extern int     sigvec          (int, struct sigvec *, struct sigvec *);
 #endif
 
+static const char *stackbuf;
 static const char *stackbot;
 static const char *stackend;
 static const char *arg0;
@@ -335,12 +336,14 @@ setup_stackovf_trap (char *const *argv, 
   {
     stack_t ss;
 
+    stackbuf = (char *) xmalloc (SIGSTKSZ);
+
     ss.ss_size = SIGSTKSZ;
-    ss.ss_sp = xmalloc (ss.ss_size);
+    ss.ss_sp = (void *) stackbuf;
     ss.ss_flags = 0;
     if (sigaltstack (&ss, (stack_t *) 0) < 0)
       {
-       xfree (ss.ss_sp);
+       xfree (stackbuf);
        error (1, errno, "sigaltstack");
       }
   }
@@ -350,7 +353,7 @@ setup_stackovf_trap (char *const *argv, 
 
   {
     struct sigstack ss;
-    char *stackbuf = xmalloc (2 * SIGSTKSZ);
+    stackbuf = (char *) xmalloc (2 * SIGSTKSZ);
 
     ss.ss_sp = stackbuf + SIGSTKSZ;
     ss.ss_onstack = 0;
@@ -406,6 +409,12 @@ Error - Do not know how to catch signals
 #endif /* HAVE_SIGVEC && defined(SV_ONSTACK) */
 #endif /* HAVE_SIGALTSTACK && defined(SA_ONSTACK) */
 
+}
+
+void
+stackovf_exit (void)
+{
+  XFREE (stackbuf);
 }
 
 #endif /* USE_STACKOVF */

-- 
  ())_. Gary V. Vaughan     gary@(oranda.demon.co.uk|gnu.org)
  ( '/  Research Scientist  http://www.oranda.demon.co.uk       ,_())____
  / )=  GNU Hacker          http://www.gnu.org/software/libtool  \'      `&
`(_~)_  Tech' Author        http://sources.redhat.com/autobook   =`---d__/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]