1 /* Wrappers around malloc and memory debugging support.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation,
5 This file is part of GNU Wget.
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Wget. If not, see <http://www.gnu.org/licenses/>.
20 Additional permission under GNU GPL version 3 section 7
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work. */
40 #include "hash.h" /* for hash_pointer */
42 /* This file implements several wrappers around the basic allocation
43 routines. This is done for two reasons: first, so that the callers
44 of these functions need not check for errors, which is easy to
45 forget. If there is not enough virtual memory for running Wget,
46 something is seriously wrong, and Wget exits with an appropriate
49 The second reason why these are useful is that, if DEBUG_MALLOC is
50 defined, they also provide a handy (if crude) malloc debugging
51 interface that checks for memory leaks. */
53 /* Croak the fatal memory error and bail out with non-zero exit
57 memfatal (const char *context, long attempted_size)
59 /* Make sure we don't try to store part of the log line, and thus
61 log_set_save_context (false);
63 /* We have different log outputs in different situations:
64 1) output without bytes information
65 2) output with bytes information */
66 if (attempted_size == UNKNOWN_ATTEMPTED_SIZE)
68 logprintf (LOG_ALWAYS,
69 _("%s: %s: Failed to allocate enough memory; memory exhausted.\n"),
74 logprintf (LOG_ALWAYS,
75 _("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
76 exec_name, context, attempted_size);
82 /* These functions end with _real because they need to be
83 distinguished from the debugging functions, and from the macros.
86 If memory debugging is not turned on, xmalloc.h defines these:
88 #define xmalloc checking_malloc
89 #define xmalloc0 checking_malloc0
90 #define xrealloc checking_realloc
91 #define xstrdup checking_strdup
92 #define xfree checking_free
94 In case of memory debugging, the definitions are a bit more
95 complex, because we want to provide more information, *and* we want
96 to call the debugging code. (The former is the reason why xmalloc
97 and friends need to be macros in the first place.) Then it looks
100 #define xmalloc(a) debugging_malloc (a, __FILE__, __LINE__)
101 #define xmalloc0(a) debugging_malloc0 (a, __FILE__, __LINE__)
102 #define xrealloc(a, b) debugging_realloc (a, b, __FILE__, __LINE__)
103 #define xstrdup(a) debugging_strdup (a, __FILE__, __LINE__)
104 #define xfree(a) debugging_free (a, __FILE__, __LINE__)
106 Each of the debugging_* functions does its magic and calls the
107 corresponding checking_* one. */
110 # define STATIC_IF_DEBUG static
112 # define STATIC_IF_DEBUG
115 STATIC_IF_DEBUG void *
116 checking_malloc (size_t size)
118 void *ptr = malloc (size);
120 memfatal ("malloc", size);
124 STATIC_IF_DEBUG void *
125 checking_malloc0 (size_t size)
127 /* Using calloc can be faster than malloc+memset because some calloc
128 implementations know when they're dealing with zeroed-out memory
129 from the system and can avoid unnecessary memset. */
130 void *ptr = calloc (1, size);
132 memfatal ("calloc", size);
136 STATIC_IF_DEBUG void *
137 checking_realloc (void *ptr, size_t newsize)
141 /* Not all Un*xes have the feature of realloc() that calling it with
142 a NULL-pointer is the same as malloc(), but it is easy to
145 newptr = realloc (ptr, newsize);
147 newptr = malloc (newsize);
149 memfatal ("realloc", newsize);
153 STATIC_IF_DEBUG char *
154 checking_strdup (const char *s)
160 copy = malloc (l + 1);
162 memfatal ("strdup", l + 1);
163 memcpy (copy, s, l + 1);
164 #else /* HAVE_STRDUP */
167 memfatal ("strdup", 1 + strlen (s));
168 #endif /* HAVE_STRDUP */
174 checking_free (void *ptr)
176 /* Wget's xfree() must not be passed a NULL pointer. This is for
177 historical reasons: pre-C89 systems were reported to bomb at
178 free(NULL), and Wget was careful to not call xfree when there was
179 a possibility of PTR being NULL. (It might have been better to
180 simply have xfree() do nothing if ptr==NULL.)
182 Since the code is already written that way, this assert simply
183 enforces the existing constraint. The benefit is double-checking
184 the logic: code that thinks it can't be passed a NULL pointer,
185 while it in fact can, aborts here. If you trip on this, either
186 the code has a pointer handling bug or should have called
187 xfree_null instead of xfree. Correctly written code should never
188 trigger this assertion.
190 The downside is that the uninitiated might not expect xfree(NULL)
191 to abort. If the assertion proves to be too much of a hassle, it
192 can be removed and a check that makes NULL a no-op placed in its
193 stead. If that is done, xfree_null is no longer needed and
194 should be removed. */
195 assert (ptr != NULL);
202 /* Crude home-grown routines for debugging some malloc-related
205 * Counting the number of malloc and free invocations, and reporting
206 the "balance", i.e. how many times more malloc was called than it
207 was the case with free.
209 * Making malloc store its entry into a simple array and free remove
210 stuff from that array. At the end, print the pointers which have
211 not been freed, along with the source file and the line number.
213 * Checking for "invalid frees", where free is called on a pointer
214 not obtained with malloc, or where the same pointer is freed
217 Note that this kind of memory leak checking strongly depends on
218 every malloc() being followed by a free(), even if the program is
219 about to finish. Wget is careful to free the data structure it
220 allocated in init.c. */
222 static int malloc_count, free_count;
224 /* Home-grown hash table of mallocs: */
226 #define SZ 100003 /* Prime just over 100,000. Increase
227 it to debug larger Wget runs. */
235 /* Find PTR's position in malloc_table. If PTR is not found, return
236 the next available position. */
239 ptr_position (const void *ptr)
241 int i = hash_pointer (ptr) % SZ;
242 for (; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
243 if (malloc_table[i].ptr == ptr)
248 /* Register PTR in malloc_table. Abort if this is not possible
249 (presumably due to the number of current allocations exceeding the
250 size of malloc_table.) */
253 register_ptr (const void *ptr, const char *file, int line)
256 if (malloc_count - free_count > SZ)
258 fprintf (stderr, "Increase SZ to a larger value and recompile.\n");
263 i = ptr_position (ptr);
264 malloc_table[i].ptr = ptr;
265 malloc_table[i].file = file;
266 malloc_table[i].line = line;
269 /* Unregister PTR from malloc_table. Return false if PTR is not
270 present in malloc_table. */
273 unregister_ptr (void *ptr)
275 int i = ptr_position (ptr);
276 if (malloc_table[i].ptr == NULL)
278 malloc_table[i].ptr = NULL;
280 /* Relocate malloc_table entries immediately following PTR. */
281 for (i = (i + 1) % SZ; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
283 const void *ptr2 = malloc_table[i].ptr;
284 /* Find the new location for the key. */
285 int j = hash_pointer (ptr2) % SZ;
286 for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
287 if (ptr2 == malloc_table[j].ptr)
288 /* No need to relocate entry at [i]; it's already at or near
289 its hash position. */
291 malloc_table[j] = malloc_table[i];
292 malloc_table[i].ptr = NULL;
299 /* Print the malloc debug stats gathered from the above information.
300 Currently this is the count of mallocs, frees, the difference
301 between the two, and the dump of the contents of malloc_table. The
302 last part are the memory leaks. */
305 print_malloc_debug_stats (void)
308 printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
309 malloc_count, free_count, malloc_count - free_count);
310 for (i = 0; i < SZ; i++)
311 if (malloc_table[i].ptr != NULL)
312 printf ("0x%0*lx: %s:%d\n", PTR_FORMAT (malloc_table[i].ptr),
313 malloc_table[i].file, malloc_table[i].line);
317 debugging_malloc (size_t size, const char *source_file, int source_line)
319 void *ptr = checking_malloc (size);
321 register_ptr (ptr, source_file, source_line);
326 debugging_malloc0 (size_t size, const char *source_file, int source_line)
328 void *ptr = checking_malloc0 (size);
330 register_ptr (ptr, source_file, source_line);
335 debugging_realloc (void *ptr, size_t newsize, const char *source_file, int source_line)
337 void *newptr = checking_realloc (ptr, newsize);
341 register_ptr (newptr, source_file, source_line);
343 else if (newptr != ptr)
345 unregister_ptr (ptr);
346 register_ptr (newptr, source_file, source_line);
352 debugging_strdup (const char *s, const char *source_file, int source_line)
354 char *copy = checking_strdup (s);
356 register_ptr (copy, source_file, source_line);
361 debugging_free (void *ptr, const char *source_file, int source_line)
363 /* See checking_free for rationale of this abort. We repeat it here
364 because we can print the file and the line where the offending
368 fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
369 exec_name, source_file, source_line);
372 if (!unregister_ptr (ptr))
374 fprintf (stderr, "%s: bad xfree(0x%0*lx) at %s:%d\n",
375 exec_name, PTR_FORMAT (ptr), source_file, source_line);
383 #endif /* DEBUG_MALLOC */