curl/lib/memdebug.c

232 lines
5.5 KiB
C
Raw Normal View History

2000-10-09 13:11:43 +02:00
#ifdef MALLOCDEBUG
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
2002-03-19 08:54:55 +01:00
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
2000-10-09 13:11:43 +02:00
*
2001-01-03 10:29:33 +01:00
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
2000-10-09 13:11:43 +02:00
*
2001-01-03 10:29:33 +01:00
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
* licenses. You may pick one of these licenses.
2000-10-09 13:11:43 +02:00
*
2001-01-03 10:29:33 +01:00
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
2000-10-09 13:11:43 +02:00
*
2001-01-03 10:29:33 +01:00
* $Id$
*****************************************************************************/
2000-10-09 13:11:43 +02:00
#include "setup.h"
#include <curl/curl.h>
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#else /* some kind of unix */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#endif
#define _MPRINTF_REPLACE
#include <curl/mprintf.h>
2000-10-09 13:11:43 +02:00
#include "urldata.h"
#include <stdio.h>
#include <string.h>
2000-11-17 15:05:43 +01:00
#include <stdlib.h>
2000-10-09 13:11:43 +02:00
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* DONT include memdebug.h here! */
struct memdebug {
int size;
double mem[1];
/* I'm hoping this is the thing with the strictest alignment
* requirements. That also means we waste some space :-( */
};
2000-10-09 13:11:43 +02:00
/*
* Note that these debug functions are very simple and they are meant to
* remain so. For advanced analysis, record a log file and write perl scripts
* to analyze them!
*
* Don't use these with multithreaded test programs!
*/
2000-10-25 09:41:11 +02:00
FILE *logfile;
2000-10-09 13:11:43 +02:00
/* this sets the log file name */
void curl_memdebug(const char *logname)
2000-10-09 13:11:43 +02:00
{
if(logname)
logfile = fopen(logname, "w");
else
logfile = stderr;
2000-10-09 13:11:43 +02:00
}
void *curl_domalloc(size_t wantedsize, int line, const char *source)
2000-10-09 13:11:43 +02:00
{
struct memdebug *mem;
size_t size;
/* alloc at least 64 bytes */
size = sizeof(struct memdebug)+wantedsize;
mem=(struct memdebug *)(malloc)(size);
if(mem) {
2001-11-29 00:19:17 +01:00
/* fill memory with junk */
memset(mem->mem, 0xA5, wantedsize);
mem->size = wantedsize;
}
if(logfile && source)
fprintf(logfile, "MEM %s:%d malloc(%d) = %p\n",
source, line, wantedsize, mem->mem);
return mem->mem;
2000-10-09 13:11:43 +02:00
}
2001-08-14 10:31:27 +02:00
char *curl_dostrdup(const char *str, int line, const char *source)
2000-10-09 13:11:43 +02:00
{
char *mem;
size_t len;
if(NULL ==str) {
fprintf(stderr, "ILLEGAL strdup() on NULL at %s:%d\n",
source, line);
exit(2);
}
len=strlen(str)+1;
mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */
memcpy(mem, str, len);
if(logfile)
fprintf(logfile, "MEM %s:%d strdup(%p) (%d) = %p\n",
source, line, str, len, mem);
2000-10-09 13:11:43 +02:00
return mem;
}
void *curl_dorealloc(void *ptr, size_t wantedsize,
int line, const char *source)
2000-10-09 13:11:43 +02:00
{
struct memdebug *mem;
size_t size = sizeof(struct memdebug)+wantedsize;
mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
mem=(struct memdebug *)(realloc)(mem, size);
if(logfile)
fprintf(logfile, "MEM %s:%d realloc(%p, %d) = %p\n",
source, line, ptr, wantedsize, mem?mem->mem:NULL);
if(mem) {
mem->size = wantedsize;
return mem->mem;
}
return NULL;
2000-10-09 13:11:43 +02:00
}
2001-08-14 10:31:27 +02:00
void curl_dofree(void *ptr, int line, const char *source)
2000-10-09 13:11:43 +02:00
{
struct memdebug *mem;
if(NULL == ptr) {
fprintf(stderr, "ILLEGAL free() on NULL at %s:%d\n",
source, line);
exit(2);
}
mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
/* destroy */
memset(mem->mem, 0x13, mem->size);
/* free for real */
(free)(mem);
if(logfile)
fprintf(logfile, "MEM %s:%d free(%p)\n", source, line, ptr);
2000-10-09 13:11:43 +02:00
}
int curl_socket(int domain, int type, int protocol, int line, char *source)
{
int sockfd=(socket)(domain, type, protocol);
if(logfile)
fprintf(logfile, "FD %s:%d socket() = %d\n",
source, line, sockfd);
return sockfd;
}
2001-03-09 16:13:34 +01:00
int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen,
2001-08-14 10:31:27 +02:00
int line, const char *source)
2000-12-18 17:13:37 +01:00
{
int sockfd=(accept)(s, addr, addrlen);
if(logfile)
fprintf(logfile, "FD %s:%d accept() = %d\n",
source, line, sockfd);
2000-12-18 17:13:37 +01:00
return sockfd;
}
/* this is our own defined way to close sockets on *ALL* platforms */
int curl_sclose(int sockfd, int line, char *source)
{
int res=sclose(sockfd);
if(logfile)
fprintf(logfile, "FD %s:%d sclose(%d)\n",
source, line, sockfd);
return res;
}
2001-08-14 10:31:27 +02:00
FILE *curl_fopen(const char *file, const char *mode,
int line, const char *source)
{
FILE *res=(fopen)(file, mode);
if(logfile)
fprintf(logfile, "FILE %s:%d fopen(\"%s\") = %p\n",
source, line, file, res);
return res;
}
2001-08-14 10:31:27 +02:00
int curl_fclose(FILE *file, int line, const char *source)
{
2002-03-08 16:31:44 +01:00
int res;
if(NULL == file) {
fprintf(stderr, "ILLEGAL flose() on NULL at %s:%d\n",
source, line);
exit(2);
}
res=(fclose)(file);
if(logfile)
fprintf(logfile, "FILE %s:%d fclose(%p)\n",
source, line, file);
return res;
}
2002-02-20 14:46:53 +01:00
#else
#ifdef VMS
int VOID_VAR_MEMDEBUG;
#endif
2000-10-09 13:11:43 +02:00
#endif /* MALLOCDEBUG */
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78
*/