00001 #ifdef CURLDEBUG
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "setup.h"
00026
00027 #include <curl/curl.h>
00028
00029 #ifdef HAVE_SYS_SOCKET_H
00030 #include <sys/socket.h>
00031 #endif
00032
00033 #define _MPRINTF_REPLACE
00034 #include <curl/mprintf.h>
00035 #include "urldata.h"
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039
00040 #ifdef HAVE_UNISTD_H
00041 #include <unistd.h>
00042 #endif
00043
00044 #define MEMDEBUG_NODEFINES
00045 #include "memory.h"
00046 #include "memdebug.h"
00047
00048 struct memdebug {
00049 size_t size;
00050 double mem[1];
00051
00052
00053 };
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #define logfile curl_debuglogfile
00064 FILE *curl_debuglogfile = NULL;
00065 static bool memlimit = FALSE;
00066 static long memsize = 0;
00067
00068
00069 void curl_memdebug(const char *logname)
00070 {
00071 if (!logfile) {
00072 if(logname)
00073 logfile = fopen(logname, "w");
00074 else
00075 logfile = stderr;
00076 #ifdef MEMDEBUG_LOG_SYNC
00077
00078 setvbuf(logfile, (char *)NULL, _IOLBF, 0);
00079 #endif
00080 }
00081 }
00082
00083
00084
00085 void curl_memlimit(long limit)
00086 {
00087 if (!memlimit) {
00088 memlimit = TRUE;
00089 memsize = limit;
00090 }
00091 }
00092
00093
00094 static bool countcheck(const char *func, int line, const char *source)
00095 {
00096
00097
00098 if(memlimit && source) {
00099 if(!memsize) {
00100 if(logfile && source)
00101 fprintf(logfile, "LIMIT %s:%d %s reached memlimit\n",
00102 source, line, func);
00103 if(source)
00104 fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
00105 source, line, func);
00106 SET_ERRNO(ENOMEM);
00107 return TRUE;
00108 }
00109 else
00110 memsize--;
00111
00112
00113 if(logfile && source)
00114 fprintf(logfile, "LIMIT %s:%d %ld ALLOCS left\n",
00115 source, line, memsize);
00116
00117 }
00118
00119 return FALSE;
00120 }
00121
00122 void *curl_domalloc(size_t wantedsize, int line, const char *source)
00123 {
00124 struct memdebug *mem;
00125 size_t size;
00126
00127 if(countcheck("malloc", line, source))
00128 return NULL;
00129
00130
00131 size = sizeof(struct memdebug)+wantedsize;
00132
00133 mem=(struct memdebug *)(Curl_cmalloc)(size);
00134 if(mem) {
00135
00136 memset(mem->mem, 0xA5, wantedsize);
00137 mem->size = wantedsize;
00138 }
00139
00140 if(logfile && source)
00141 fprintf(logfile, "MEM %s:%d malloc(%zd) = %p\n",
00142 source, line, wantedsize, mem ? mem->mem : 0);
00143 return (mem ? mem->mem : NULL);
00144 }
00145
00146 void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
00147 int line, const char *source)
00148 {
00149 struct memdebug *mem;
00150 size_t size, user_size;
00151
00152 if(countcheck("calloc", line, source))
00153 return NULL;
00154
00155
00156 user_size = wanted_size * wanted_elements;
00157 size = sizeof(struct memdebug) + user_size;
00158
00159 mem = (struct memdebug *)(Curl_cmalloc)(size);
00160 if(mem) {
00161
00162 memset(mem->mem, 0, user_size);
00163 mem->size = user_size;
00164 }
00165
00166 if(logfile && source)
00167 fprintf(logfile, "MEM %s:%d calloc(%u,%u) = %p\n",
00168 source, line, wanted_elements, wanted_size, mem ? mem->mem : 0);
00169 return (mem ? mem->mem : NULL);
00170 }
00171
00172 char *curl_dostrdup(const char *str, int line, const char *source)
00173 {
00174 char *mem;
00175 size_t len;
00176
00177 DEBUGASSERT(str != NULL);
00178
00179 if(countcheck("strdup", line, source))
00180 return NULL;
00181
00182 len=strlen(str)+1;
00183
00184 mem=curl_domalloc(len, 0, NULL);
00185 if (mem)
00186 memcpy(mem, str, len);
00187
00188 if(logfile)
00189 fprintf(logfile, "MEM %s:%d strdup(%p) (%zd) = %p\n",
00190 source, line, str, len, mem);
00191
00192 return mem;
00193 }
00194
00195
00196
00197 void *curl_dorealloc(void *ptr, size_t wantedsize,
00198 int line, const char *source)
00199 {
00200 struct memdebug *mem=NULL;
00201
00202 size_t size = sizeof(struct memdebug)+wantedsize;
00203
00204 if(countcheck("realloc", line, source))
00205 return NULL;
00206
00207 if(ptr)
00208 mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
00209
00210 mem=(struct memdebug *)(Curl_crealloc)(mem, size);
00211 if(logfile)
00212 fprintf(logfile, "MEM %s:%d realloc(%p, %zd) = %p\n",
00213 source, line, ptr, wantedsize, mem?mem->mem:NULL);
00214
00215 if(mem) {
00216 mem->size = wantedsize;
00217 return mem->mem;
00218 }
00219
00220 return NULL;
00221 }
00222
00223 void curl_dofree(void *ptr, int line, const char *source)
00224 {
00225 struct memdebug *mem;
00226
00227 DEBUGASSERT(ptr != NULL);
00228
00229 mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
00230
00231
00232 memset(mem->mem, 0x13, mem->size);
00233
00234
00235 (Curl_cfree)(mem);
00236
00237 if(logfile)
00238 fprintf(logfile, "MEM %s:%d free(%p)\n", source, line, ptr);
00239 }
00240
00241 int curl_socket(int domain, int type, int protocol, int line,
00242 const char *source)
00243 {
00244 int sockfd=(socket)(domain, type, protocol);
00245 if(logfile && (sockfd!=-1))
00246 fprintf(logfile, "FD %s:%d socket() = %d\n",
00247 source, line, sockfd);
00248 return sockfd;
00249 }
00250
00251 int curl_accept(int s, void *saddr, void *saddrlen,
00252 int line, const char *source)
00253 {
00254 struct sockaddr *addr = (struct sockaddr *)saddr;
00255 socklen_t *addrlen = (socklen_t *)saddrlen;
00256 int sockfd=(accept)(s, addr, addrlen);
00257 if(logfile)
00258 fprintf(logfile, "FD %s:%d accept() = %d\n",
00259 source, line, sockfd);
00260 return sockfd;
00261 }
00262
00263
00264 int curl_sclose(int sockfd, int line, const char *source)
00265 {
00266 int res=sclose(sockfd);
00267 if(logfile)
00268 fprintf(logfile, "FD %s:%d sclose(%d)\n",
00269 source, line, sockfd);
00270 return res;
00271 }
00272
00273 FILE *curl_fopen(const char *file, const char *mode,
00274 int line, const char *source)
00275 {
00276 FILE *res=(fopen)(file, mode);
00277 if(logfile)
00278 fprintf(logfile, "FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
00279 source, line, file, mode, res);
00280 return res;
00281 }
00282
00283 FILE *curl_fdopen(int filedes, const char *mode,
00284 int line, const char *source)
00285 {
00286 FILE *res=(fdopen)(filedes, mode);
00287 if(logfile)
00288 fprintf(logfile, "FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
00289 source, line, filedes, mode, res);
00290 return res;
00291 }
00292
00293 int curl_fclose(FILE *file, int line, const char *source)
00294 {
00295 int res;
00296
00297 DEBUGASSERT(file != NULL);
00298
00299 res=(fclose)(file);
00300 if(logfile)
00301 fprintf(logfile, "FILE %s:%d fclose(%p)\n",
00302 source, line, file);
00303 return res;
00304 }
00305 #else
00306 #ifdef VMS
00307 int VOID_VAR_MEMDEBUG;
00308 #else
00309
00310 void curl_memdebug(void) {}
00311 #endif
00312 #endif