mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Committed memory debugging stuff.
Published in <sxs1yw34pt4.fsf@florida.arsdigita.de>.
This commit is contained in:
parent
d8c9ce30aa
commit
1cddc05edb
@ -1,3 +1,12 @@
|
|||||||
|
2000-11-22 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||||
|
|
||||||
|
* ftp.c (getftp): ftp_getaddress() returns a malloc'ed copy of the
|
||||||
|
string; no need to strdup() it.
|
||||||
|
(getftp): Make pwd_len a local variable.
|
||||||
|
(ftp_loop): Free PWD before returning.
|
||||||
|
|
||||||
|
* init.c (cleanup): Free opt.ftp_pass only if it's non-NULL.
|
||||||
|
|
||||||
2000-11-22 Hrvoje Niksic <hniksic@arsdigita.com>
|
2000-11-22 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||||
|
|
||||||
* all: Use xfree() instead of free.
|
* all: Use xfree() instead of free.
|
||||||
|
10
src/ftp.c
10
src/ftp.c
@ -57,9 +57,11 @@ extern int h_errno;
|
|||||||
|
|
||||||
extern char ftp_last_respline[];
|
extern char ftp_last_respline[];
|
||||||
|
|
||||||
|
/* #### Global variables?? These two should be members of struct
|
||||||
|
ccon! */
|
||||||
|
|
||||||
static enum stype host_type=ST_UNIX;
|
static enum stype host_type=ST_UNIX;
|
||||||
static char *pwd;
|
static char *pwd;
|
||||||
static int pwd_len;
|
|
||||||
|
|
||||||
/* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
|
/* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
|
||||||
the string S, and return the number converted to long, if found, 0
|
the string S, and return the number converted to long, if found, 0
|
||||||
@ -133,7 +135,7 @@ getftp (const struct urlinfo *u, long *len, long restval, ccon *con)
|
|||||||
search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
|
search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
|
||||||
user = user ? user : opt.ftp_acc;
|
user = user ? user : opt.ftp_acc;
|
||||||
if (!opt.ftp_pass)
|
if (!opt.ftp_pass)
|
||||||
opt.ftp_pass = xstrdup (ftp_getaddress ());
|
opt.ftp_pass = ftp_getaddress ();
|
||||||
passwd = passwd ? passwd : opt.ftp_pass;
|
passwd = passwd ? passwd : opt.ftp_pass;
|
||||||
assert (user && passwd);
|
assert (user && passwd);
|
||||||
|
|
||||||
@ -279,7 +281,6 @@ Error in server response, closing control connection.\n"));
|
|||||||
if (!opt.server_response)
|
if (!opt.server_response)
|
||||||
logprintf (LOG_VERBOSE, "==> PWD ... ");
|
logprintf (LOG_VERBOSE, "==> PWD ... ");
|
||||||
err = ftp_pwd(&con->rbuf, &pwd);
|
err = ftp_pwd(&con->rbuf, &pwd);
|
||||||
pwd_len = strlen(pwd);
|
|
||||||
/* FTPRERR */
|
/* FTPRERR */
|
||||||
switch (err)
|
switch (err)
|
||||||
{
|
{
|
||||||
@ -354,6 +355,7 @@ Error in server response, closing control connection.\n"));
|
|||||||
it to VMS style as VMS does not like leading slashes */
|
it to VMS style as VMS does not like leading slashes */
|
||||||
if (*(u->dir) == '/')
|
if (*(u->dir) == '/')
|
||||||
{
|
{
|
||||||
|
int pwd_len = strlen (pwd);
|
||||||
char *result = (char *)alloca (strlen (u->dir) + pwd_len + 10);
|
char *result = (char *)alloca (strlen (u->dir) + pwd_len + 10);
|
||||||
*result = '\0';
|
*result = '\0';
|
||||||
switch (host_type)
|
switch (host_type)
|
||||||
@ -1634,6 +1636,8 @@ ftp_loop (struct urlinfo *u, int *dt)
|
|||||||
/* If a connection was left, quench it. */
|
/* If a connection was left, quench it. */
|
||||||
if (rbuf_initialized_p (&con.rbuf))
|
if (rbuf_initialized_p (&con.rbuf))
|
||||||
CLOSE (RBUF_FD (&con.rbuf));
|
CLOSE (RBUF_FD (&con.rbuf));
|
||||||
|
FREE_MAYBE (pwd);
|
||||||
|
pwd = NULL;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +372,9 @@ sufmatch (const char **list, const char *what)
|
|||||||
function returns a short `username@' form, accepted by most
|
function returns a short `username@' form, accepted by most
|
||||||
anonymous servers.
|
anonymous servers.
|
||||||
|
|
||||||
|
The returned string is generated by malloc() and should be freed
|
||||||
|
using free().
|
||||||
|
|
||||||
If not even the username cannot be divined, it means things are
|
If not even the username cannot be divined, it means things are
|
||||||
seriously fucked up, and Wget exits. */
|
seriously fucked up, and Wget exits. */
|
||||||
char *
|
char *
|
||||||
|
@ -566,3 +566,10 @@ get_urls_html (const char *file, const char *this_url, int dash_p_leaf_HTML,
|
|||||||
read_file_free (fm);
|
read_file_free (fm);
|
||||||
return closure.head;
|
return closure.head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_html_url (void)
|
||||||
|
{
|
||||||
|
FREE_MAYBE (interesting_tags);
|
||||||
|
FREE_MAYBE (interesting_attributes);
|
||||||
|
}
|
||||||
|
@ -981,6 +981,10 @@ check_user_specified_header (const char *s)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanup_html_url PARAMS ((void));
|
||||||
|
void downloaded_files_free PARAMS ((void));
|
||||||
|
|
||||||
|
|
||||||
/* Free the memory allocated by global variables. */
|
/* Free the memory allocated by global variables. */
|
||||||
void
|
void
|
||||||
cleanup (void)
|
cleanup (void)
|
||||||
@ -992,6 +996,8 @@ cleanup (void)
|
|||||||
free_netrc (netrc_list);
|
free_netrc (netrc_list);
|
||||||
if (opt.dfp)
|
if (opt.dfp)
|
||||||
fclose (opt.dfp);
|
fclose (opt.dfp);
|
||||||
|
cleanup_html_url ();
|
||||||
|
downloaded_files_free ();
|
||||||
FREE_MAYBE (opt.lfilename);
|
FREE_MAYBE (opt.lfilename);
|
||||||
xfree (opt.dir_prefix);
|
xfree (opt.dir_prefix);
|
||||||
FREE_MAYBE (opt.input_filename);
|
FREE_MAYBE (opt.input_filename);
|
||||||
@ -1004,7 +1010,7 @@ cleanup (void)
|
|||||||
free_vec (opt.follow_tags);
|
free_vec (opt.follow_tags);
|
||||||
free_vec (opt.ignore_tags);
|
free_vec (opt.ignore_tags);
|
||||||
xfree (opt.ftp_acc);
|
xfree (opt.ftp_acc);
|
||||||
xfree (opt.ftp_pass);
|
FREE_MAYBE (opt.ftp_pass);
|
||||||
FREE_MAYBE (opt.ftp_proxy);
|
FREE_MAYBE (opt.ftp_proxy);
|
||||||
FREE_MAYBE (opt.http_proxy);
|
FREE_MAYBE (opt.http_proxy);
|
||||||
free_vec (opt.no_proxy);
|
free_vec (opt.no_proxy);
|
||||||
|
@ -809,6 +809,9 @@ Can't timestamp and not clobber old files at the same time.\n"));
|
|||||||
}
|
}
|
||||||
log_close ();
|
log_close ();
|
||||||
cleanup ();
|
cleanup ();
|
||||||
|
#ifdef DEBUG_MALLOC
|
||||||
|
print_malloc_debug_stats ();
|
||||||
|
#endif
|
||||||
if (status == RETROK)
|
if (status == RETROK)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
29
src/url.c
29
src/url.c
@ -1577,6 +1577,14 @@ write_backup_file (const char *file, downloaded_file_t downloaded_file_return)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _downloaded_file_list {
|
||||||
|
char* file;
|
||||||
|
downloaded_file_t download_type;
|
||||||
|
struct _downloaded_file_list* next;
|
||||||
|
} downloaded_file_list;
|
||||||
|
|
||||||
|
static downloaded_file_list *downloaded_files;
|
||||||
|
|
||||||
/* Remembers which files have been downloaded. In the standard case, should be
|
/* Remembers which files have been downloaded. In the standard case, should be
|
||||||
called with mode == FILE_DOWNLOADED_NORMALLY for each file we actually
|
called with mode == FILE_DOWNLOADED_NORMALLY for each file we actually
|
||||||
download successfully (i.e. not for ones we have failures on or that we skip
|
download successfully (i.e. not for ones we have failures on or that we skip
|
||||||
@ -1592,15 +1600,7 @@ write_backup_file (const char *file, downloaded_file_t downloaded_file_return)
|
|||||||
downloaded_file_t
|
downloaded_file_t
|
||||||
downloaded_file (downloaded_file_t mode, const char* file)
|
downloaded_file (downloaded_file_t mode, const char* file)
|
||||||
{
|
{
|
||||||
typedef struct _downloaded_file_list
|
|
||||||
{
|
|
||||||
char* file;
|
|
||||||
downloaded_file_t download_type;
|
|
||||||
struct _downloaded_file_list* next;
|
|
||||||
} downloaded_file_list;
|
|
||||||
|
|
||||||
boolean found_file = FALSE;
|
boolean found_file = FALSE;
|
||||||
static downloaded_file_list* downloaded_files = NULL;
|
|
||||||
downloaded_file_list* rover = downloaded_files;
|
downloaded_file_list* rover = downloaded_files;
|
||||||
|
|
||||||
while (rover != NULL)
|
while (rover != NULL)
|
||||||
@ -1628,6 +1628,19 @@ downloaded_file (downloaded_file_t mode, const char* file)
|
|||||||
return FILE_NOT_ALREADY_DOWNLOADED;
|
return FILE_NOT_ALREADY_DOWNLOADED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
downloaded_files_free (void)
|
||||||
|
{
|
||||||
|
downloaded_file_list* rover = downloaded_files;
|
||||||
|
while (rover)
|
||||||
|
{
|
||||||
|
downloaded_file_list *next = rover->next;
|
||||||
|
xfree (rover->file);
|
||||||
|
xfree (rover);
|
||||||
|
rover = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialization of static stuff. */
|
/* Initialization of static stuff. */
|
||||||
void
|
void
|
||||||
|
227
src/utils.c
227
src/utils.c
@ -60,80 +60,249 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
extern int errno;
|
extern int errno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This section implements several wrappers around the basic
|
||||||
|
allocation routines. This is done for two reasons: first, so that
|
||||||
|
the callers of these functions need not consistently check for
|
||||||
|
errors. If there is not enough virtual memory for running Wget,
|
||||||
|
something is seriously wrong, and Wget exits with an appropriate
|
||||||
|
error message.
|
||||||
|
|
||||||
|
The second reason why these are useful is that, if DEBUG_MALLOC is
|
||||||
|
defined, they also provide a handy (if crude) malloc debugging
|
||||||
|
interface that checks memory leaks. */
|
||||||
|
|
||||||
/* Croak the fatal memory error and bail out with non-zero exit
|
/* Croak the fatal memory error and bail out with non-zero exit
|
||||||
status. */
|
status. */
|
||||||
static void
|
static void
|
||||||
memfatal (const char *s)
|
memfatal (const char *what)
|
||||||
{
|
{
|
||||||
/* HACK: expose save_log_p from log.c, so we can turn it off in
|
/* HACK: expose save_log_p from log.c, so we can turn it off in
|
||||||
order to prevent saving the log. Saving the log is dangerous
|
order to prevent saving the log. Saving the log is dangerous
|
||||||
because logprintf() and logputs() can call malloc(), so this
|
because logprintf() and logputs() can call malloc(), so this
|
||||||
could infloop. When logging is turned off, infloop can no longer
|
could infloop. When logging is turned off, infloop can no longer
|
||||||
happen. */
|
happen.
|
||||||
|
|
||||||
|
#### This is no longer really necessary because the new routines
|
||||||
|
in log.c cons only if the line exceeds eighty characters. But
|
||||||
|
this can come at the end of a line, so it's OK to be careful.
|
||||||
|
|
||||||
|
On a more serious note, it would be good to have a
|
||||||
|
log_forced_shutdown() routine that exposes this cleanly. */
|
||||||
extern int save_log_p;
|
extern int save_log_p;
|
||||||
|
|
||||||
save_log_p = 0;
|
save_log_p = 0;
|
||||||
logprintf (LOG_ALWAYS, _("%s: %s: Not enough memory.\n"), exec_name, s);
|
logprintf (LOG_ALWAYS, _("%s: %s: Not enough memory.\n"), exec_name, what);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xmalloc, xrealloc and xstrdup exit the program if there is not
|
/* These functions end with _real because they need to be
|
||||||
enough memory. xstrdup also implements strdup on systems that do
|
distinguished from the debugging functions, and from the macros.
|
||||||
not have it. xfree is provided to make leak-tracking easier.
|
Explanation follows:
|
||||||
Currently it's a no-op. */
|
|
||||||
|
If memory debugging is not turned on, wget.h defines these:
|
||||||
|
|
||||||
|
#define xmalloc xmalloc_real
|
||||||
|
#define xfree xfree_real
|
||||||
|
#define xrealloc xrealloc_real
|
||||||
|
#define xstrdup xstrdup_real
|
||||||
|
|
||||||
|
In case of memory debugging, the definitions are a bit more
|
||||||
|
complex, because we want to provide more information, *and* we want
|
||||||
|
to call the debugging code. (The former is the reason why xmalloc
|
||||||
|
and friends need to be macros in the first place.) Then it looks
|
||||||
|
like this:
|
||||||
|
|
||||||
|
#define xmalloc(a) xmalloc_debug (a, __FILE__, __LINE__)
|
||||||
|
#define xfree(a) xfree_debug (a, __FILE__, __LINE__)
|
||||||
|
#define xrealloc(a, b) xrealloc_debug (a, b, __FILE__, __LINE__)
|
||||||
|
#define xstrdup(a) xstrdup_debug (a, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
Each of the *_debug function does its magic and calls the real one. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xmalloc (size_t size)
|
xmalloc_real (size_t size)
|
||||||
{
|
{
|
||||||
void *res;
|
void *ptr = malloc (size);
|
||||||
|
if (!ptr)
|
||||||
res = malloc (size);
|
|
||||||
if (!res)
|
|
||||||
memfatal ("malloc");
|
memfatal ("malloc");
|
||||||
return res;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xfree (void *ptr)
|
xfree_real (void *ptr)
|
||||||
{
|
{
|
||||||
free (ptr);
|
free (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xrealloc (void *obj, size_t size)
|
xrealloc_real (void *ptr, size_t newsize)
|
||||||
{
|
{
|
||||||
void *res;
|
void *newptr;
|
||||||
|
|
||||||
/* Not all Un*xes have the feature of realloc() that calling it with
|
/* Not all Un*xes have the feature of realloc() that calling it with
|
||||||
a NULL-pointer is the same as malloc(), but it is easy to
|
a NULL-pointer is the same as malloc(), but it is easy to
|
||||||
simulate. */
|
simulate. */
|
||||||
if (obj)
|
if (ptr)
|
||||||
res = realloc (obj, size);
|
newptr = realloc (ptr, newsize);
|
||||||
else
|
else
|
||||||
res = malloc (size);
|
newptr = malloc (newsize);
|
||||||
if (!res)
|
if (!newptr)
|
||||||
memfatal ("realloc");
|
memfatal ("realloc");
|
||||||
return res;
|
return newptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
xstrdup (const char *s)
|
xstrdup_real (const char *s)
|
||||||
{
|
{
|
||||||
|
char *copy;
|
||||||
|
|
||||||
#ifndef HAVE_STRDUP
|
#ifndef HAVE_STRDUP
|
||||||
int l = strlen (s);
|
int l = strlen (s);
|
||||||
char *s1 = malloc (l + 1);
|
copy = malloc (l + 1);
|
||||||
if (!s1)
|
if (!copy)
|
||||||
memfatal ("strdup");
|
memfatal ("strdup");
|
||||||
memcpy (s1, s, l + 1);
|
memcpy (copy, s, l + 1);
|
||||||
return s1;
|
|
||||||
#else /* HAVE_STRDUP */
|
#else /* HAVE_STRDUP */
|
||||||
char *s1 = strdup (s);
|
copy = strdup (s);
|
||||||
if (!s1)
|
if (!copy)
|
||||||
memfatal ("strdup");
|
memfatal ("strdup");
|
||||||
return s1;
|
|
||||||
#endif /* HAVE_STRDUP */
|
#endif /* HAVE_STRDUP */
|
||||||
|
|
||||||
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_MALLOC
|
||||||
|
|
||||||
|
/* Crude home-grown routines for debugging some malloc-related
|
||||||
|
problems. Featured:
|
||||||
|
|
||||||
|
* Counting the number of malloc and free invocations, and reporting
|
||||||
|
the "balance", i.e. how many times more malloc was called than it
|
||||||
|
was the case with free.
|
||||||
|
|
||||||
|
* Making malloc store its entry into a simple array and free remove
|
||||||
|
stuff from that array. At the end, print the pointers which have
|
||||||
|
not been freed, along with the source file and the line number.
|
||||||
|
This also has the side-effect of detecting freeing memory that
|
||||||
|
was never allocated.
|
||||||
|
|
||||||
|
Note that this kind of memory leak checking strongly depends on
|
||||||
|
every malloc() being followed by a free(), even if the program is
|
||||||
|
about to finish. Wget is careful to free the data structure it
|
||||||
|
allocated in init.c. */
|
||||||
|
|
||||||
|
static int malloc_count, free_count;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char *ptr;
|
||||||
|
const char *file;
|
||||||
|
int line;
|
||||||
|
} malloc_debug[100000];
|
||||||
|
|
||||||
|
/* Both register_ptr and unregister_ptr take O(n) operations to run,
|
||||||
|
which can be a real problem. It would be nice to use a hash table
|
||||||
|
for malloc_debug, but the functions in hash.c are not suitable
|
||||||
|
because they can call malloc() themselves. Maybe it would work if
|
||||||
|
the hash table were preallocated to a huge size, and if we set the
|
||||||
|
rehash threshold to 1.0. */
|
||||||
|
|
||||||
|
/* Register PTR in malloc_debug. Abort if this is not possible
|
||||||
|
(presumably due to the number of current allocations exceeding the
|
||||||
|
size of malloc_debug.) */
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_ptr (void *ptr, const char *file, int line)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
|
||||||
|
if (malloc_debug[i].ptr == NULL)
|
||||||
|
{
|
||||||
|
malloc_debug[i].ptr = ptr;
|
||||||
|
malloc_debug[i].file = file;
|
||||||
|
malloc_debug[i].line = line;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unregister PTR from malloc_debug. Abort if PTR is not present in
|
||||||
|
malloc_debug. (This catches calling free() with a bogus pointer.) */
|
||||||
|
|
||||||
|
static void
|
||||||
|
unregister_ptr (void *ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
|
||||||
|
if (malloc_debug[i].ptr == ptr)
|
||||||
|
{
|
||||||
|
malloc_debug[i].ptr = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the malloc debug stats that can be gathered from the above
|
||||||
|
information. Currently this is the count of mallocs, frees, the
|
||||||
|
difference between the two, and the dump of the contents of
|
||||||
|
malloc_debug. The last part are the memory leaks. */
|
||||||
|
|
||||||
|
void
|
||||||
|
print_malloc_debug_stats (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
|
||||||
|
malloc_count, free_count, malloc_count - free_count);
|
||||||
|
for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
|
||||||
|
if (malloc_debug[i].ptr != NULL)
|
||||||
|
printf ("0x%08ld: %s:%d\n", (long)malloc_debug[i].ptr,
|
||||||
|
malloc_debug[i].file, malloc_debug[i].line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xmalloc_debug (size_t size, const char *source_file, int source_line)
|
||||||
|
{
|
||||||
|
void *ptr = xmalloc_real (size);
|
||||||
|
++malloc_count;
|
||||||
|
register_ptr (ptr, source_file, source_line);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xfree_debug (void *ptr, const char *source_file, int source_line)
|
||||||
|
{
|
||||||
|
assert (ptr != NULL);
|
||||||
|
++free_count;
|
||||||
|
unregister_ptr (ptr);
|
||||||
|
xfree_real (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xrealloc_debug (void *ptr, size_t newsize, const char *source_file, int source_line)
|
||||||
|
{
|
||||||
|
void *newptr = xrealloc_real (ptr, newsize);
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
++malloc_count;
|
||||||
|
register_ptr (newptr, source_file, source_line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unregister_ptr (ptr);
|
||||||
|
register_ptr (newptr, source_file, source_line);
|
||||||
|
}
|
||||||
|
return newptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
xstrdup_debug (const char *s, const char *source_file, int source_line)
|
||||||
|
{
|
||||||
|
char *copy = xstrdup_real (s);
|
||||||
|
++malloc_count;
|
||||||
|
register_ptr (copy, source_file, source_line);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DEBUG_MALLOC */
|
||||||
|
|
||||||
/* Copy the string formed by two pointers (one on the beginning, other
|
/* Copy the string formed by two pointers (one on the beginning, other
|
||||||
on the char after the last char) to a new, malloc-ed location.
|
on the char after the last char) to a new, malloc-ed location.
|
||||||
|
@ -42,6 +42,10 @@ struct file_memory {
|
|||||||
char *time_str PARAMS ((time_t *));
|
char *time_str PARAMS ((time_t *));
|
||||||
const char *uerrmsg PARAMS ((uerr_t));
|
const char *uerrmsg PARAMS ((uerr_t));
|
||||||
|
|
||||||
|
#ifdef DEBUG_MALLOC
|
||||||
|
void print_malloc_debug_stats ();
|
||||||
|
#endif
|
||||||
|
|
||||||
char *strdupdelim PARAMS ((const char *, const char *));
|
char *strdupdelim PARAMS ((const char *, const char *));
|
||||||
char **sepstring PARAMS ((const char *));
|
char **sepstring PARAMS ((const char *));
|
||||||
int frontcmp PARAMS ((const char *, const char *));
|
int frontcmp PARAMS ((const char *, const char *));
|
||||||
|
29
src/wget.h
29
src/wget.h
@ -98,10 +98,31 @@ void debug_logprintf ();
|
|||||||
void logputs PARAMS ((enum log_options, const char *));
|
void logputs PARAMS ((enum log_options, const char *));
|
||||||
|
|
||||||
/* Defined in `utils.c', but used literally everywhere. */
|
/* Defined in `utils.c', but used literally everywhere. */
|
||||||
void *xmalloc PARAMS ((size_t));
|
#ifndef DEBUG_MALLOC
|
||||||
void xfree PARAMS ((void *));
|
|
||||||
void *xrealloc PARAMS ((void *, size_t));
|
#define xmalloc xmalloc_real
|
||||||
char *xstrdup PARAMS ((const char *));
|
#define xfree xfree_real
|
||||||
|
#define xrealloc xrealloc_real
|
||||||
|
#define xstrdup xstrdup_real
|
||||||
|
|
||||||
|
void *xmalloc_real PARAMS ((size_t));
|
||||||
|
void xfree_real PARAMS ((void *));
|
||||||
|
void *xrealloc_real PARAMS ((void *, size_t));
|
||||||
|
char *xstrdup_real PARAMS ((const char *));
|
||||||
|
|
||||||
|
#else /* DEBUG_MALLOC */
|
||||||
|
|
||||||
|
#define xmalloc(s) xmalloc_debug (s, __FILE__, __LINE__)
|
||||||
|
#define xfree(p) xfree_debug (p, __FILE__, __LINE__)
|
||||||
|
#define xrealloc(p, s) xrealloc_debug (p, s, __FILE__, __LINE__)
|
||||||
|
#define xstrdup(p) xstrdup_debug (p, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
void *xmalloc_debug PARAMS ((size_t, const char *, int));
|
||||||
|
void xfree_debug PARAMS ((void *, const char *, int));
|
||||||
|
void *xrealloc_debug PARAMS ((void *, size_t, const char *, int));
|
||||||
|
char *xstrdup_debug PARAMS ((const char *, const char *, int));
|
||||||
|
|
||||||
|
#endif /* DEBUG_MALLOC */
|
||||||
|
|
||||||
/* #### Find a better place for this. */
|
/* #### Find a better place for this. */
|
||||||
/* The log file to which Wget writes to after HUP. */
|
/* The log file to which Wget writes to after HUP. */
|
||||||
|
Loading…
Reference in New Issue
Block a user