1 /* Wrappers around malloc and memory debugging support.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007 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. */
41 #include "hash.h" /* for hash_pointer */
43 /* This file implements several wrappers around the basic allocation
44 routines. This is done for two reasons: first, so that the callers
45 of these functions need not check for errors, which is easy to
46 forget. If there is not enough virtual memory for running Wget,
47 something is seriously wrong, and Wget exits with an appropriate
50 The second reason why these are useful is that, if DEBUG_MALLOC is
51 defined, they also provide a handy (if crude) malloc debugging
52 interface that checks for memory leaks. */
54 /* Croak the fatal memory error and bail out with non-zero exit
58 memfatal (const char *context, long attempted_size)
60 /* Make sure we don't try to store part of the log line, and thus
62 log_set_save_context (false);
63 logprintf (LOG_ALWAYS,
64 _("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
65 exec_name, context, attempted_size);
69 /* These functions end with _real because they need to be
70 distinguished from the debugging functions, and from the macros.
73 If memory debugging is not turned on, xmalloc.h defines these:
75 #define xmalloc checking_malloc
76 #define xmalloc0 checking_malloc0
77 #define xrealloc checking_realloc
78 #define xstrdup checking_strdup
79 #define xfree checking_free
81 In case of memory debugging, the definitions are a bit more
82 complex, because we want to provide more information, *and* we want
83 to call the debugging code. (The former is the reason why xmalloc
84 and friends need to be macros in the first place.) Then it looks
87 #define xmalloc(a) debugging_malloc (a, __FILE__, __LINE__)
88 #define xmalloc0(a) debugging_malloc0 (a, __FILE__, __LINE__)
89 #define xrealloc(a, b) debugging_realloc (a, b, __FILE__, __LINE__)
90 #define xstrdup(a) debugging_strdup (a, __FILE__, __LINE__)
91 #define xfree(a) debugging_free (a, __FILE__, __LINE__)
93 Each of the debugging_* functions does its magic and calls the
94 corresponding checking_* one. */
97 # define STATIC_IF_DEBUG static
99 # define STATIC_IF_DEBUG
102 STATIC_IF_DEBUG void *
103 checking_malloc (size_t size)
105 void *ptr = malloc (size);
107 memfatal ("malloc", size);
111 STATIC_IF_DEBUG void *
112 checking_malloc0 (size_t size)
114 /* Using calloc can be faster than malloc+memset because some calloc
115 implementations know when they're dealing with zeroed-out memory
116 from the system and can avoid unnecessary memset. */
117 void *ptr = calloc (1, size);
119 memfatal ("calloc", size);
123 STATIC_IF_DEBUG void *
124 checking_realloc (void *ptr, size_t newsize)
128 /* Not all Un*xes have the feature of realloc() that calling it with
129 a NULL-pointer is the same as malloc(), but it is easy to
132 newptr = realloc (ptr, newsize);
134 newptr = malloc (newsize);
136 memfatal ("realloc", newsize);
140 STATIC_IF_DEBUG char *
141 checking_strdup (const char *s)
147 copy = malloc (l + 1);
149 memfatal ("strdup", l + 1);
150 memcpy (copy, s, l + 1);
151 #else /* HAVE_STRDUP */
154 memfatal ("strdup", 1 + strlen (s));
155 #endif /* HAVE_STRDUP */
161 checking_free (void *ptr)
163 /* Wget's xfree() must not be passed a NULL pointer. This is for
164 historical reasons: pre-C89 systems were reported to bomb at
165 free(NULL), and Wget was careful to not call xfree when there was
166 a possibility of PTR being NULL. (It might have been better to
167 simply have xfree() do nothing if ptr==NULL.)
169 Since the code is already written that way, this assert simply
170 enforces the existing constraint. The benefit is double-checking
171 the logic: code that thinks it can't be passed a NULL pointer,
172 while it in fact can, aborts here. If you trip on this, either
173 the code has a pointer handling bug or should have called
174 xfree_null instead of xfree. Correctly written code should never
175 trigger this assertion.
177 The downside is that the uninitiated might not expect xfree(NULL)
178 to abort. If the assertion proves to be too much of a hassle, it
179 can be removed and a check that makes NULL a no-op placed in its
180 stead. If that is done, xfree_null is no longer needed and
181 should be removed. */
182 assert (ptr != NULL);
189 /* Crude home-grown routines for debugging some malloc-related
192 * Counting the number of malloc and free invocations, and reporting
193 the "balance", i.e. how many times more malloc was called than it
194 was the case with free.
196 * Making malloc store its entry into a simple array and free remove
197 stuff from that array. At the end, print the pointers which have
198 not been freed, along with the source file and the line number.
200 * Checking for "invalid frees", where free is called on a pointer
201 not obtained with malloc, or where the same pointer is freed
204 Note that this kind of memory leak checking strongly depends on
205 every malloc() being followed by a free(), even if the program is
206 about to finish. Wget is careful to free the data structure it
207 allocated in init.c. */
209 static int malloc_count, free_count;
211 /* Home-grown hash table of mallocs: */
213 #define SZ 100003 /* Prime just over 100,000. Increase
214 it to debug larger Wget runs. */
222 /* Find PTR's position in malloc_table. If PTR is not found, return
223 the next available position. */
226 ptr_position (const void *ptr)
228 int i = hash_pointer (ptr) % SZ;
229 for (; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
230 if (malloc_table[i].ptr == ptr)
235 /* Register PTR in malloc_table. Abort if this is not possible
236 (presumably due to the number of current allocations exceeding the
237 size of malloc_table.) */
240 register_ptr (const void *ptr, const char *file, int line)
243 if (malloc_count - free_count > SZ)
245 fprintf (stderr, "Increase SZ to a larger value and recompile.\n");
250 i = ptr_position (ptr);
251 malloc_table[i].ptr = ptr;
252 malloc_table[i].file = file;
253 malloc_table[i].line = line;
256 /* Unregister PTR from malloc_table. Return false if PTR is not
257 present in malloc_table. */
260 unregister_ptr (void *ptr)
262 int i = ptr_position (ptr);
263 if (malloc_table[i].ptr == NULL)
265 malloc_table[i].ptr = NULL;
267 /* Relocate malloc_table entries immediately following PTR. */
268 for (i = (i + 1) % SZ; malloc_table[i].ptr != NULL; i = (i + 1) % SZ)
270 const void *ptr2 = malloc_table[i].ptr;
271 /* Find the new location for the key. */
272 int j = hash_pointer (ptr2) % SZ;
273 for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
274 if (ptr2 == malloc_table[j].ptr)
275 /* No need to relocate entry at [i]; it's already at or near
276 its hash position. */
278 malloc_table[j] = malloc_table[i];
279 malloc_table[i].ptr = NULL;
286 /* Print the malloc debug stats gathered from the above information.
287 Currently this is the count of mallocs, frees, the difference
288 between the two, and the dump of the contents of malloc_table. The
289 last part are the memory leaks. */
292 print_malloc_debug_stats (void)
295 printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
296 malloc_count, free_count, malloc_count - free_count);
297 for (i = 0; i < SZ; i++)
298 if (malloc_table[i].ptr != NULL)
299 printf ("0x%0*lx: %s:%d\n", PTR_FORMAT (malloc_table[i].ptr),
300 malloc_table[i].file, malloc_table[i].line);
304 debugging_malloc (size_t size, const char *source_file, int source_line)
306 void *ptr = checking_malloc (size);
308 register_ptr (ptr, source_file, source_line);
313 debugging_malloc0 (size_t size, const char *source_file, int source_line)
315 void *ptr = checking_malloc0 (size);
317 register_ptr (ptr, source_file, source_line);
322 debugging_realloc (void *ptr, size_t newsize, const char *source_file, int source_line)
324 void *newptr = checking_realloc (ptr, newsize);
328 register_ptr (newptr, source_file, source_line);
330 else if (newptr != ptr)
332 unregister_ptr (ptr);
333 register_ptr (newptr, source_file, source_line);
339 debugging_strdup (const char *s, const char *source_file, int source_line)
341 char *copy = checking_strdup (s);
343 register_ptr (copy, source_file, source_line);
348 debugging_free (void *ptr, const char *source_file, int source_line)
350 /* See checking_free for rationale of this abort. We repeat it here
351 because we can print the file and the line where the offending
355 fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
356 exec_name, source_file, source_line);
359 if (!unregister_ptr (ptr))
361 fprintf (stderr, "%s: bad xfree(0x%0*lx) at %s:%d\n",
362 exec_name, PTR_FORMAT (ptr), source_file, source_line);
370 #endif /* DEBUG_MALLOC */