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 number a little over 100,000.
222 Increase the table size if you need
223 to debug larger Wget runs. */
231 /* Find PTR's position in malloc_table. If PTR is not found, return
232 the next available position. */
235 ptr_position (const void *ptr)
237 int i = hash_pointer (ptr) % SZ;
238 for (; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
239 if (malloc_table[i].ptr == ptr)
244 /* Register PTR in malloc_table. Abort if this is not possible
245 (presumably due to the number of current allocations exceeding the
246 size of malloc_table.) */
249 register_ptr (const void *ptr, const char *file, int line)
252 if (malloc_count - free_count > SZ)
255 i = ptr_position (ptr);
256 malloc_table[i].ptr = ptr;
257 malloc_table[i].file = file;
258 malloc_table[i].line = line;
261 /* Unregister PTR from malloc_table. Return 0 if PTR is not present
265 unregister_ptr (void *ptr)
267 int i = ptr_position (ptr);
268 if (malloc_table[i].ptr == NULL)
270 malloc_table[i].ptr = NULL;
272 /* Relocate malloc_table entries immediately following PTR. */
273 for (i = (i + 1) % SZ; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
275 const void *ptr2 = malloc_table[i].ptr;
276 /* Find the new location for the key. */
277 int j = hash_pointer (ptr2) % SZ;
278 for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
279 if (ptr2 == malloc_table[j].ptr)
280 /* No need to relocate entry at [i]; it's already at or near
281 its hash position. */
283 malloc_table[j] = malloc_table[i];
284 malloc_table[i].ptr = NULL;
291 /* Print the malloc debug stats gathered from the above information.
292 Currently this is the count of mallocs, frees, the difference
293 between the two, and the dump of the contents of malloc_table. The
294 last part are the memory leaks. */
297 print_malloc_debug_stats (void)
300 printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
301 malloc_count, free_count, malloc_count - free_count);
302 for (i = 0; i < SZ; i++)
303 if (malloc_table[i].ptr != NULL)
304 printf ("0x%0*lx: %s:%d\n", 2 * sizeof (void *),
305 (long) malloc_table[i].ptr,
306 malloc_table[i].file, malloc_table[i].line);
310 debugging_malloc (size_t size, const char *source_file, int source_line)
312 void *ptr = checking_malloc (size);
314 register_ptr (ptr, source_file, source_line);
319 debugging_malloc0 (size_t size, const char *source_file, int source_line)
321 void *ptr = checking_malloc0 (size);
323 register_ptr (ptr, source_file, source_line);
328 debugging_realloc (void *ptr, size_t newsize, const char *source_file, int source_line)
330 void *newptr = checking_realloc (ptr, newsize);
334 register_ptr (newptr, source_file, source_line);
336 else if (newptr != ptr)
338 unregister_ptr (ptr);
339 register_ptr (newptr, source_file, source_line);
345 debugging_strdup (const char *s, const char *source_file, int source_line)
347 char *copy = checking_strdup (s);
349 register_ptr (copy, source_file, source_line);
354 debugging_free (void *ptr, const char *source_file, int source_line)
356 /* See checking_free for rationale of this abort. We repeat it here
357 because we can print the file and the line where the offending
361 fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
362 exec_name, source_file, source_line);
365 if (!unregister_ptr (ptr))
367 fprintf (stderr, "%s: bad xfree(%0*lx) at %s:%d\n",
368 exec_name, 2 * sizeof (void *), (long) ptr,
369 source_file, source_line);
377 #endif /* DEBUG_MALLOC */