1 /* Wrappers around malloc and memory debugging support.
2 Copyright (C) 2005 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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables. You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL". If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so. If you do not wish to do
28 so, delete this exception statement from your version. */
36 #else /* not HAVE_STRING_H */
38 #endif /* not HAVE_STRING_H */
39 #include <sys/types.h>
45 #include "hash.h" /* for hash_pointer */
51 /* This file implements several wrappers around the basic allocation
52 routines. This is done for two reasons: first, so that the callers
53 of these functions need not check for errors, which is easy to
54 forget. If there is not enough virtual memory for running Wget,
55 something is seriously wrong, and Wget exits with an appropriate
58 The second reason why these are useful is that, if DEBUG_MALLOC is
59 defined, they also provide a handy (if crude) malloc debugging
60 interface that checks for memory leaks. */
62 /* Croak the fatal memory error and bail out with non-zero exit
66 memfatal (const char *context, long attempted_size)
68 /* Make sure we don't try to store part of the log line, and thus
70 log_set_save_context (0);
71 logprintf (LOG_ALWAYS,
72 _("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
73 exec_name, context, attempted_size);
77 /* These functions end with _real because they need to be
78 distinguished from the debugging functions, and from the macros.
81 If memory debugging is not turned on, xmalloc.h defines these:
83 #define xmalloc checking_malloc
84 #define xmalloc0 checking_malloc0
85 #define xrealloc checking_realloc
86 #define xstrdup checking_strdup
87 #define xfree checking_free
89 In case of memory debugging, the definitions are a bit more
90 complex, because we want to provide more information, *and* we want
91 to call the debugging code. (The former is the reason why xmalloc
92 and friends need to be macros in the first place.) Then it looks
95 #define xmalloc(a) debugging_malloc (a, __FILE__, __LINE__)
96 #define xmalloc0(a) debugging_malloc0 (a, __FILE__, __LINE__)
97 #define xrealloc(a, b) debugging_realloc (a, b, __FILE__, __LINE__)
98 #define xstrdup(a) debugging_strdup (a, __FILE__, __LINE__)
99 #define xfree(a) debugging_free (a, __FILE__, __LINE__)
101 Each of the debugging_* functions does its magic and calls the
102 corresponding checking_* one. */
105 # define STATIC_IF_DEBUG static
107 # define STATIC_IF_DEBUG
110 STATIC_IF_DEBUG void *
111 checking_malloc (size_t size)
113 void *ptr = malloc (size);
115 memfatal ("malloc", size);
119 STATIC_IF_DEBUG void *
120 checking_malloc0 (size_t size)
122 /* Using calloc can be faster than malloc+memset because some calloc
123 implementations know when they're dealing with zeroed-out memory
124 from the system and can avoid unnecessary memset. */
125 void *ptr = calloc (1, size);
127 memfatal ("calloc", size);
131 STATIC_IF_DEBUG void *
132 checking_realloc (void *ptr, size_t newsize)
136 /* Not all Un*xes have the feature of realloc() that calling it with
137 a NULL-pointer is the same as malloc(), but it is easy to
140 newptr = realloc (ptr, newsize);
142 newptr = malloc (newsize);
144 memfatal ("realloc", newsize);
148 STATIC_IF_DEBUG char *
149 checking_strdup (const char *s)
155 copy = malloc (l + 1);
157 memfatal ("strdup", l + 1);
158 memcpy (copy, s, l + 1);
159 #else /* HAVE_STRDUP */
162 memfatal ("strdup", 1 + strlen (s));
163 #endif /* HAVE_STRDUP */
169 checking_free (void *ptr)
171 /* Wget's xfree() must not be passed a NULL pointer. This is for
172 historical reasons: pre-C89 systems were reported to bomb at
173 free(NULL), and Wget was careful to not call xfree when there was
174 a possibility of PTR being NULL. (It might have been better to
175 simply have xfree() do nothing if ptr==NULL.)
177 Since the code is already written that way, this assert simply
178 enforces the existing constraint. The benefit is double-checking
179 the logic: code that thinks it can't be passed a NULL pointer,
180 while it in fact can, aborts here. If you trip on this, either
181 the code has a pointer handling bug or should have called
182 xfree_null instead of xfree. Correctly written code should never
183 trigger this assertion.
185 The downside is that the uninitiated might not expect xfree(NULL)
186 to abort. If the assertion proves to be too much of a hassle, it
187 can be removed and a check that makes NULL a no-op placed in its
188 stead. If that is done, xfree_null is no longer needed and
189 should be removed. */
190 assert (ptr != NULL);
197 /* Crude home-grown routines for debugging some malloc-related
200 * Counting the number of malloc and free invocations, and reporting
201 the "balance", i.e. how many times more malloc was called than it
202 was the case with free.
204 * Making malloc store its entry into a simple array and free remove
205 stuff from that array. At the end, print the pointers which have
206 not been freed, along with the source file and the line number.
208 * Checking for "invalid frees", where free is called on a pointer
209 not obtained with malloc, or where the same pointer is freed
212 Note that this kind of memory leak checking strongly depends on
213 every malloc() being followed by a free(), even if the program is
214 about to finish. Wget is careful to free the data structure it
215 allocated in init.c. */
217 static int malloc_count, free_count;
219 /* Home-grown hash table of mallocs: */
221 #define SZ 100003 /* Prime just over 100,000. Increase
222 it to debug larger Wget runs. */
230 /* Find PTR's position in malloc_table. If PTR is not found, return
231 the next available position. */
234 ptr_position (const void *ptr)
236 int i = hash_pointer (ptr) % SZ;
237 for (; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
238 if (malloc_table[i].ptr == ptr)
243 /* Register PTR in malloc_table. Abort if this is not possible
244 (presumably due to the number of current allocations exceeding the
245 size of malloc_table.) */
248 register_ptr (const void *ptr, const char *file, int line)
251 if (malloc_count - free_count > SZ)
253 fprintf (stderr, "Increase SZ to a larger value and recompile.\n");
258 i = ptr_position (ptr);
259 malloc_table[i].ptr = ptr;
260 malloc_table[i].file = file;
261 malloc_table[i].line = line;
264 /* Unregister PTR from malloc_table. Return 0 if PTR is not present
268 unregister_ptr (void *ptr)
270 int i = ptr_position (ptr);
271 if (malloc_table[i].ptr == NULL)
273 malloc_table[i].ptr = NULL;
275 /* Relocate malloc_table entries immediately following PTR. */
276 for (i = (i + 1) % SZ; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
278 const void *ptr2 = malloc_table[i].ptr;
279 /* Find the new location for the key. */
280 int j = hash_pointer (ptr2) % SZ;
281 for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
282 if (ptr2 == malloc_table[j].ptr)
283 /* No need to relocate entry at [i]; it's already at or near
284 its hash position. */
286 malloc_table[j] = malloc_table[i];
287 malloc_table[i].ptr = NULL;
294 /* Print the malloc debug stats gathered from the above information.
295 Currently this is the count of mallocs, frees, the difference
296 between the two, and the dump of the contents of malloc_table. The
297 last part are the memory leaks. */
300 print_malloc_debug_stats (void)
303 printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
304 malloc_count, free_count, malloc_count - free_count);
305 for (i = 0; i < SZ; i++)
306 if (malloc_table[i].ptr != NULL)
307 printf ("0x%0*lx: %s:%d\n", 2 * sizeof (void *),
308 (long) malloc_table[i].ptr,
309 malloc_table[i].file, malloc_table[i].line);
313 debugging_malloc (size_t size, const char *source_file, int source_line)
315 void *ptr = checking_malloc (size);
317 register_ptr (ptr, source_file, source_line);
322 debugging_malloc0 (size_t size, const char *source_file, int source_line)
324 void *ptr = checking_malloc0 (size);
326 register_ptr (ptr, source_file, source_line);
331 debugging_realloc (void *ptr, size_t newsize, const char *source_file, int source_line)
333 void *newptr = checking_realloc (ptr, newsize);
337 register_ptr (newptr, source_file, source_line);
339 else if (newptr != ptr)
341 unregister_ptr (ptr);
342 register_ptr (newptr, source_file, source_line);
348 debugging_strdup (const char *s, const char *source_file, int source_line)
350 char *copy = checking_strdup (s);
352 register_ptr (copy, source_file, source_line);
357 debugging_free (void *ptr, const char *source_file, int source_line)
359 /* See checking_free for rationale of this abort. We repeat it here
360 because we can print the file and the line where the offending
364 fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
365 exec_name, source_file, source_line);
368 if (!unregister_ptr (ptr))
370 fprintf (stderr, "%s: bad xfree(%0*lx) at %s:%d\n",
371 exec_name, 2 * sizeof (void *), (long) ptr,
372 source_file, source_line);
380 #endif /* DEBUG_MALLOC */