1
/* Wrappers around malloc and memory debugging support.
2
Copyright (C) 2003, 2004, 2005, 2006, 2007,
3
2008 Free Software Foundation, Inc.
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 */