]> sjero.net Git - wget/commitdiff
[svn] Abort on xfree(NULL).
authorhniksic <devnull@localhost>
Sun, 2 Nov 2003 21:12:49 +0000 (13:12 -0800)
committerhniksic <devnull@localhost>
Sun, 2 Nov 2003 21:12:49 +0000 (13:12 -0800)
src/ChangeLog
src/html-url.c
src/init.c
src/wget.h
src/xmalloc.c
src/xmalloc.h

index 62b68db3146a244bdfa2ebe1edfd142b88d0c17f..9622f2830641f781d681b6e9dd015a87e2e69706 100644 (file)
@@ -1,3 +1,17 @@
+2003-11-02  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * html-url.c (cleanup_html_url): Destroy the hash tables, don't
+       just call free on them.
+       (init_interesting): Use hash_table_put instead of string_set_add
+       because we don't need the strdup that the latter function
+       performs.
+
+       * init.c (cleanup): Don't pass NULL to cookie_jar_delete.
+
+       * xmalloc.c (xfree_real): Abort when passed a NULL pointer.
+       (xfree_debug): Print at the file and line of the offending call to
+       free.
+
 2003-11-02  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * wget.h: Retired the `boolean' type.  Moved the DEFAULT_LOGFILE
index efbae629e8855c03322d2a422fe3e0cecab73edf..54dbf382f0402845c87e863d5f2ee6ac9e4b1ba9 100644 (file)
@@ -227,9 +227,10 @@ init_interesting (void)
   /* Add the attributes we care about. */
   interesting_attributes = make_nocase_string_hash_table (10);
   for (i = 0; i < countof (additional_attributes); i++)
-    string_set_add (interesting_attributes, additional_attributes[i]);
+    hash_table_put (interesting_attributes, additional_attributes[i], "1");
   for (i = 0; i < countof (tag_url_attributes); i++)
-    string_set_add (interesting_attributes, tag_url_attributes[i].attr_name);
+    hash_table_put (interesting_attributes,
+                   tag_url_attributes[i].attr_name, "1");
 }
 
 /* Find the value of attribute named NAME in the taginfo TAG.  If the
@@ -715,6 +716,10 @@ get_urls_file (const char *file)
 void
 cleanup_html_url (void)
 {
-  xfree_null (interesting_tags);
-  xfree_null (interesting_attributes);
+  /* Destroy the hash tables.  The hash table keys and values are not
+     allocated by this code, so we don't need to free them here.  */
+  if (interesting_tags)
+    hash_table_destroy (interesting_tags);
+  if (interesting_attributes)
+    hash_table_destroy (interesting_attributes);
 }
index 7f666f9e6dc3accb7e1ab718c58a08b7d4a175d4..391b32b9e5f705de4630d44150c78830b25a618b 100644 (file)
@@ -1319,7 +1319,8 @@ cleanup (void)
   cleanup_html_url ();
   downloaded_files_free ();
   host_cleanup ();
-  cookie_jar_delete (wget_cookie_jar);
+  if (wget_cookie_jar)
+    cookie_jar_delete (wget_cookie_jar);
 
   {
     extern acc_t *netrc_list;
index b75aab60429d2d97694a202d299b48dee410757b..9cac5c759f6db4c3f05be9ec65ab4b8646567d34 100644 (file)
@@ -40,11 +40,6 @@ so, delete this exception statement from your version.  */
 # define NDEBUG
 #endif
 
-/* Define this if you want primitive but extensive malloc debugging.
-   It will make Wget extremely slow, so only do it in development
-   builds.  */
-#undef DEBUG_MALLOC
-
 #ifndef PARAMS
 # if PROTOTYPES
 #  define PARAMS(args) args
index 2f2a9006304477a803901c3b8c56fc50c1138c15..311506ec19faf68a72959624665670377d1cd1a1 100644 (file)
@@ -83,7 +83,7 @@ memfatal (const char *context, long attempted_size)
      #define xmalloc0 xmalloc0_real
      #define xrealloc xrealloc_real
      #define xstrdup xstrdup_real
-     #define xfree free
+     #define xfree xfree_real
 
    In case of memory debugging, the definitions are a bit more
    complex, because we want to provide more information, *and* we want
@@ -93,9 +93,9 @@ memfatal (const char *context, long attempted_size)
 
      #define xmalloc(a) xmalloc_debug (a, __FILE__, __LINE__)
      #define xmalloc0(a) xmalloc0_debug (a, __FILE__, __LINE__)
-     #define xfree(a)   xfree_debug (a, __FILE__, __LINE__)
      #define xrealloc(a, b) xrealloc_debug (a, b, __FILE__, __LINE__)
      #define xstrdup(a) xstrdup_debug (a, __FILE__, __LINE__)
+     #define xfree(a) xfree_debug (a, __FILE__, __LINE__)
 
    Each of the *_debug function does its magic and calls the real one.  */
 
@@ -163,6 +163,30 @@ xstrdup_real (const char *s)
   return copy;
 }
 
+STATIC_IF_DEBUG void
+xfree_real (void *ptr)
+{
+  /* Wget's xfree() must not be passed a NULL pointer.  This is for
+     historical reasons: many pre-C89 systems were known to bomb at
+     free(NULL), and Wget was careful to use xfree_null when there is
+     a possibility of PTR being NULL.  (It might have been better to
+     simply have xfree() do nothing if ptr==NULL.)
+
+     Since the code is already written that way, this assert simply
+     enforces that constraint.  Code that thinks it doesn't deal with
+     NULL, and it in fact does, aborts immediately.  If you trip on
+     this, either the code has a pointer handling bug or should have
+     called xfree_null instead of xfree.  Correctly written code
+     should never trigger this assertion.
+
+     If the assertion proves to be too much of a hassle, it can be
+     removed and a check that makes NULL a no-op placed in its stead.
+     If that is done, xfree_null is no longer needed and should be
+     removed.  */
+  assert (ptr != NULL);
+  free (ptr);
+}
+
 /* xfree_real is unnecessary because free doesn't require any special
    functionality.  */
 \f
@@ -300,10 +324,18 @@ xstrdup_debug (const char *s, const char *source_file, int source_line)
 void
 xfree_debug (void *ptr, const char *source_file, int source_line)
 {
-  assert (ptr != NULL);
+  /* See xfree_real for rationale of this abort.  We repeat it here
+     because we can print the file and the line where the offending
+     free occurred.  */
+  if (ptr == NULL)
+    {
+      fprintf ("%s: xfree(NULL) at %s:%d\n",
+              exec_name, source_file, source_line);
+      abort ();
+    }
   ++free_count;
   unregister_ptr (ptr);
-  free (ptr);
+  xfree_real (ptr);
 }
 
 #endif /* DEBUG_MALLOC */
index d738afc502f57b2f8ebce6bc83273be3122da6a1..7729e5ababb545e09d447e8584b0a0eda262bdb2 100644 (file)
@@ -30,10 +30,18 @@ so, delete this exception statement from your version.  */
 #ifndef XMALLOC_H
 #define XMALLOC_H
 
+/* Define this if you want primitive but extensive malloc debugging.
+   It will make Wget extremely slow, so only do it in development
+   builds.  */
+#define DEBUG_MALLOC
+
 /* When DEBUG_MALLOC is not defined (which is normally the case), the
    allocation functions directly map to *_real wrappers.  In the
    DEBUG_MALLOC mode, they also record the file and line where the
-   offending malloc/free/... was invoked.  */
+   offending malloc/free/... was invoked.
+
+   *Note*: xfree(NULL) aborts.  If the pointer you're freeing can be
+   NULL, use xfree_null instead.  */
 
 #ifndef DEBUG_MALLOC
 
@@ -41,26 +49,27 @@ so, delete this exception statement from your version.  */
 #define xmalloc0 xmalloc0_real
 #define xrealloc xrealloc_real
 #define xstrdup  xstrdup_real
-#define xfree    free
+#define xfree    xfree_real
 
 void *xmalloc_real PARAMS ((size_t));
 void *xmalloc0_real PARAMS ((size_t));
 void *xrealloc_real PARAMS ((void *, size_t));
 char *xstrdup_real PARAMS ((const char *));
+void xfree_real PARAMS ((void *));
 
 #else  /* DEBUG_MALLOC */
 
 #define xmalloc(s)     xmalloc_debug (s, __FILE__, __LINE__)
 #define xmalloc0(s)    xmalloc0_debug (s, __FILE__, __LINE__)
-#define xfree(p)       xfree_debug (p, __FILE__, __LINE__)
 #define xrealloc(p, s) xrealloc_debug (p, s, __FILE__, __LINE__)
 #define xstrdup(p)     xstrdup_debug (p, __FILE__, __LINE__)
+#define xfree(p)       xfree_debug (p, __FILE__, __LINE__)
 
 void *xmalloc_debug PARAMS ((size_t, const char *, int));
 void *xmalloc0_debug PARAMS ((size_t, const char *, int));
-void xfree_debug PARAMS ((void *, const char *, int));
 void *xrealloc_debug PARAMS ((void *, size_t, const char *, int));
 char *xstrdup_debug PARAMS ((const char *, const char *, int));
+void xfree_debug PARAMS ((void *, const char *, int));
 
 #endif /* DEBUG_MALLOC */