1 /* Wrappers around malloc and memory debugging support.
2 Copyright (C) 2003-2006 Free Software Foundation, Inc.
4 This file is part of GNU Wget.
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Wget. If not, see <http://www.gnu.org/licenses/>.
19 In addition, as a special exception, the Free Software Foundation
20 gives permission to link the code of its release of Wget with the
21 OpenSSL project's "OpenSSL" library (or with modified versions of it
22 that use the same license as the "OpenSSL" library), and distribute
23 the linked executables. You must obey the GNU General Public License
24 in all respects for all of the code used other than "OpenSSL". If you
25 modify this file, you may extend this exception to your version of the
26 file, but you are not obligated to do so. If you do not wish to do
27 so, delete this exception statement from your version. */
39 #include "hash.h" /* for hash_pointer */
41 /* This file implements several wrappers around the basic allocation
42 routines. This is done for two reasons: first, so that the callers
43 of these functions need not check for errors, which is easy to
44 forget. If there is not enough virtual memory for running Wget,
45 something is seriously wrong, and Wget exits with an appropriate
48 The second reason why these are useful is that, if DEBUG_MALLOC is
49 defined, they also provide a handy (if crude) malloc debugging
50 interface that checks for memory leaks. */
52 /* Croak the fatal memory error and bail out with non-zero exit
56 memfatal (const char *context, long attempted_size)
58 /* Make sure we don't try to store part of the log line, and thus
60 log_set_save_context (false);
61 logprintf (LOG_ALWAYS,
62 _("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
63 exec_name, context, attempted_size);
67 /* These functions end with _real because they need to be
68 distinguished from the debugging functions, and from the macros.
71 If memory debugging is not turned on, xmalloc.h defines these:
73 #define xmalloc checking_malloc
74 #define xmalloc0 checking_malloc0
75 #define xrealloc checking_realloc
76 #define xstrdup checking_strdup
77 #define xfree checking_free
79 In case of memory debugging, the definitions are a bit more
80 complex, because we want to provide more information, *and* we want
81 to call the debugging code. (The former is the reason why xmalloc
82 and friends need to be macros in the first place.) Then it looks
85 #define xmalloc(a) debugging_malloc (a, __FILE__, __LINE__)
86 #define xmalloc0(a) debugging_malloc0 (a, __FILE__, __LINE__)
87 #define xrealloc(a, b) debugging_realloc (a, b, __FILE__, __LINE__)
88 #define xstrdup(a) debugging_strdup (a, __FILE__, __LINE__)
89 #define xfree(a) debugging_free (a, __FILE__, __LINE__)
91 Each of the debugging_* functions does its magic and calls the
92 corresponding checking_* one. */
95 # define STATIC_IF_DEBUG static
97 # define STATIC_IF_DEBUG
100 STATIC_IF_DEBUG void *
101 checking_malloc (size_t size)
103 void *ptr = malloc (size);
105 memfatal ("malloc", size);
109 STATIC_IF_DEBUG void *
110 checking_malloc0 (size_t size)
112 /* Using calloc can be faster than malloc+memset because some calloc
113 implementations know when they're dealing with zeroed-out memory
114 from the system and can avoid unnecessary memset. */
115 void *ptr = calloc (1, size);
117 memfatal ("calloc", size);
121 STATIC_IF_DEBUG void *
122 checking_realloc (void *ptr, size_t newsize)
126 /* Not all Un*xes have the feature of realloc() that calling it with
127 a NULL-pointer is the same as malloc(), but it is easy to
130 newptr = realloc (ptr, newsize);
132 newptr = malloc (newsize);
134 memfatal ("realloc", newsize);
138 STATIC_IF_DEBUG char *
139 checking_strdup (const char *s)
145 copy = malloc (l + 1);
147 memfatal ("strdup", l + 1);
148 memcpy (copy, s, l + 1);
149 #else /* HAVE_STRDUP */
152 memfatal ("strdup", 1 + strlen (s));
153 #endif /* HAVE_STRDUP */
159 checking_free (void *ptr)
161 /* Wget's xfree() must not be passed a NULL pointer. This is for
162 historical reasons: pre-C89 systems were reported to bomb at
163 free(NULL), and Wget was careful to not call xfree when there was
164 a possibility of PTR being NULL. (It might have been better to
165 simply have xfree() do nothing if ptr==NULL.)
167 Since the code is already written that way, this assert simply
168 enforces the existing constraint. The benefit is double-checking
169 the logic: code that thinks it can't be passed a NULL pointer,
170 while it in fact can, aborts here. If you trip on this, either
171 the code has a pointer handling bug or should have called
172 xfree_null instead of xfree. Correctly written code should never
173 trigger this assertion.
175 The downside is that the uninitiated might not expect xfree(NULL)
176 to abort. If the assertion proves to be too much of a hassle, it
177 can be removed and a check that makes NULL a no-op placed in its
178 stead. If that is done, xfree_null is no longer needed and
179 should be removed. */
180 assert (ptr != NULL);
187 /* Crude home-grown routines for debugging some malloc-related
190 * Counting the number of malloc and free invocations, and reporting
191 the "balance", i.e. how many times more malloc was called than it
192 was the case with free.
194 * Making malloc store its entry into a simple array and free remove
195 stuff from that array. At the end, print the pointers which have
196 not been freed, along with the source file and the line number.
198 * Checking for "invalid frees", where free is called on a pointer
199 not obtained with malloc, or where the same pointer is freed
202 Note that this kind of memory leak checking strongly depends on
203 every malloc() being followed by a free(), even if the program is
204 about to finish. Wget is careful to free the data structure it
205 allocated in init.c. */
207 static int malloc_count, free_count;
209 /* Home-grown hash table of mallocs: */
211 #define SZ 100003 /* Prime just over 100,000. Increase
212 it to debug larger Wget runs. */
220 /* Find PTR's position in malloc_table. If PTR is not found, return
221 the next available position. */
224 ptr_position (const void *ptr)
226 int i = hash_pointer (ptr) % SZ;
227 for (; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
228 if (malloc_table[i].ptr == ptr)
233 /* Register PTR in malloc_table. Abort if this is not possible
234 (presumably due to the number of current allocations exceeding the
235 size of malloc_table.) */
238 register_ptr (const void *ptr, const char *file, int line)
241 if (malloc_count - free_count > SZ)
243 fprintf (stderr, "Increase SZ to a larger value and recompile.\n");
248 i = ptr_position (ptr);
249 malloc_table[i].ptr = ptr;
250 malloc_table[i].file = file;
251 malloc_table[i].line = line;
254 /* Unregister PTR from malloc_table. Return false if PTR is not
255 present in malloc_table. */
258 unregister_ptr (void *ptr)
260 int i = ptr_position (ptr);
261 if (malloc_table[i].ptr == NULL)
263 malloc_table[i].ptr = NULL;
265 /* Relocate malloc_table entries immediately following PTR. */
266 for (i = (i + 1) % SZ; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
268 const void *ptr2 = malloc_table[i].ptr;
269 /* Find the new location for the key. */
270 int j = hash_pointer (ptr2) % SZ;
271 for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
272 if (ptr2 == malloc_table[j].ptr)
273 /* No need to relocate entry at [i]; it's already at or near
274 its hash position. */
276 malloc_table[j] = malloc_table[i];
277 malloc_table[i].ptr = NULL;
284 /* Print the malloc debug stats gathered from the above information.
285 Currently this is the count of mallocs, frees, the difference
286 between the two, and the dump of the contents of malloc_table. The
287 last part are the memory leaks. */
290 print_malloc_debug_stats (void)
293 printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
294 malloc_count, free_count, malloc_count - free_count);
295 for (i = 0; i < SZ; i++)
296 if (malloc_table[i].ptr != NULL)
297 printf ("0x%0*lx: %s:%d\n", PTR_FORMAT (malloc_table[i].ptr),
298 malloc_table[i].file, malloc_table[i].line);
302 debugging_malloc (size_t size, const char *source_file, int source_line)
304 void *ptr = checking_malloc (size);
306 register_ptr (ptr, source_file, source_line);
311 debugging_malloc0 (size_t size, const char *source_file, int source_line)
313 void *ptr = checking_malloc0 (size);
315 register_ptr (ptr, source_file, source_line);
320 debugging_realloc (void *ptr, size_t newsize, const char *source_file, int source_line)
322 void *newptr = checking_realloc (ptr, newsize);
326 register_ptr (newptr, source_file, source_line);
328 else if (newptr != ptr)
330 unregister_ptr (ptr);
331 register_ptr (newptr, source_file, source_line);
337 debugging_strdup (const char *s, const char *source_file, int source_line)
339 char *copy = checking_strdup (s);
341 register_ptr (copy, source_file, source_line);
346 debugging_free (void *ptr, const char *source_file, int source_line)
348 /* See checking_free for rationale of this abort. We repeat it here
349 because we can print the file and the line where the offending
353 fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
354 exec_name, source_file, source_line);
357 if (!unregister_ptr (ptr))
359 fprintf (stderr, "%s: bad xfree(0x%0*lx) at %s:%d\n",
360 exec_name, PTR_FORMAT (ptr), source_file, source_line);
368 #endif /* DEBUG_MALLOC */