113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#ifdef CURLDEBUG 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci#include <curl/curl.h> 3013498266Sopenharmony_ci 3113498266Sopenharmony_ci#include "urldata.h" 3213498266Sopenharmony_ci 3313498266Sopenharmony_ci#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */ 3413498266Sopenharmony_ci 3513498266Sopenharmony_ci/* The last 3 #include files should be in this order */ 3613498266Sopenharmony_ci#include "curl_printf.h" 3713498266Sopenharmony_ci#include "curl_memory.h" 3813498266Sopenharmony_ci#include "memdebug.h" 3913498266Sopenharmony_ci 4013498266Sopenharmony_cistruct memdebug { 4113498266Sopenharmony_ci size_t size; 4213498266Sopenharmony_ci union { 4313498266Sopenharmony_ci curl_off_t o; 4413498266Sopenharmony_ci double d; 4513498266Sopenharmony_ci void *p; 4613498266Sopenharmony_ci } mem[1]; 4713498266Sopenharmony_ci /* I'm hoping this is the thing with the strictest alignment 4813498266Sopenharmony_ci * requirements. That also means we waste some space :-( */ 4913498266Sopenharmony_ci}; 5013498266Sopenharmony_ci 5113498266Sopenharmony_ci/* 5213498266Sopenharmony_ci * Note that these debug functions are very simple and they are meant to 5313498266Sopenharmony_ci * remain so. For advanced analysis, record a log file and write perl scripts 5413498266Sopenharmony_ci * to analyze them! 5513498266Sopenharmony_ci * 5613498266Sopenharmony_ci * Don't use these with multithreaded test programs! 5713498266Sopenharmony_ci */ 5813498266Sopenharmony_ci 5913498266Sopenharmony_ciFILE *curl_dbg_logfile = NULL; 6013498266Sopenharmony_cistatic bool registered_cleanup = FALSE; /* atexit registered cleanup */ 6113498266Sopenharmony_cistatic bool memlimit = FALSE; /* enable memory limit */ 6213498266Sopenharmony_cistatic long memsize = 0; /* set number of mallocs allowed */ 6313498266Sopenharmony_ci 6413498266Sopenharmony_ci/* LeakSantizier (LSAN) calls _exit() instead of exit() when a leak is detected 6513498266Sopenharmony_ci on exit so the logfile must be closed explicitly or data could be lost. 6613498266Sopenharmony_ci Though _exit() does not call atexit handlers such as this, LSAN's call to 6713498266Sopenharmony_ci _exit() comes after the atexit handlers are called. curl/curl#6620 */ 6813498266Sopenharmony_cistatic void curl_dbg_cleanup(void) 6913498266Sopenharmony_ci{ 7013498266Sopenharmony_ci if(curl_dbg_logfile && 7113498266Sopenharmony_ci curl_dbg_logfile != stderr && 7213498266Sopenharmony_ci curl_dbg_logfile != stdout) { 7313498266Sopenharmony_ci fclose(curl_dbg_logfile); 7413498266Sopenharmony_ci } 7513498266Sopenharmony_ci curl_dbg_logfile = NULL; 7613498266Sopenharmony_ci} 7713498266Sopenharmony_ci 7813498266Sopenharmony_ci/* this sets the log file name */ 7913498266Sopenharmony_civoid curl_dbg_memdebug(const char *logname) 8013498266Sopenharmony_ci{ 8113498266Sopenharmony_ci if(!curl_dbg_logfile) { 8213498266Sopenharmony_ci if(logname && *logname) 8313498266Sopenharmony_ci curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT); 8413498266Sopenharmony_ci else 8513498266Sopenharmony_ci curl_dbg_logfile = stderr; 8613498266Sopenharmony_ci#ifdef MEMDEBUG_LOG_SYNC 8713498266Sopenharmony_ci /* Flush the log file after every line so the log isn't lost in a crash */ 8813498266Sopenharmony_ci if(curl_dbg_logfile) 8913498266Sopenharmony_ci setbuf(curl_dbg_logfile, (char *)NULL); 9013498266Sopenharmony_ci#endif 9113498266Sopenharmony_ci } 9213498266Sopenharmony_ci if(!registered_cleanup) 9313498266Sopenharmony_ci registered_cleanup = !atexit(curl_dbg_cleanup); 9413498266Sopenharmony_ci} 9513498266Sopenharmony_ci 9613498266Sopenharmony_ci/* This function sets the number of malloc() calls that should return 9713498266Sopenharmony_ci successfully! */ 9813498266Sopenharmony_civoid curl_dbg_memlimit(long limit) 9913498266Sopenharmony_ci{ 10013498266Sopenharmony_ci if(!memlimit) { 10113498266Sopenharmony_ci memlimit = TRUE; 10213498266Sopenharmony_ci memsize = limit; 10313498266Sopenharmony_ci } 10413498266Sopenharmony_ci} 10513498266Sopenharmony_ci 10613498266Sopenharmony_ci/* returns TRUE if this isn't allowed! */ 10713498266Sopenharmony_cistatic bool countcheck(const char *func, int line, const char *source) 10813498266Sopenharmony_ci{ 10913498266Sopenharmony_ci /* if source is NULL, then the call is made internally and this check 11013498266Sopenharmony_ci should not be made */ 11113498266Sopenharmony_ci if(memlimit && source) { 11213498266Sopenharmony_ci if(!memsize) { 11313498266Sopenharmony_ci /* log to file */ 11413498266Sopenharmony_ci curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", 11513498266Sopenharmony_ci source, line, func); 11613498266Sopenharmony_ci /* log to stderr also */ 11713498266Sopenharmony_ci fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", 11813498266Sopenharmony_ci source, line, func); 11913498266Sopenharmony_ci fflush(curl_dbg_logfile); /* because it might crash now */ 12013498266Sopenharmony_ci errno = ENOMEM; 12113498266Sopenharmony_ci return TRUE; /* RETURN ERROR! */ 12213498266Sopenharmony_ci } 12313498266Sopenharmony_ci else 12413498266Sopenharmony_ci memsize--; /* countdown */ 12513498266Sopenharmony_ci 12613498266Sopenharmony_ci 12713498266Sopenharmony_ci } 12813498266Sopenharmony_ci 12913498266Sopenharmony_ci return FALSE; /* allow this */ 13013498266Sopenharmony_ci} 13113498266Sopenharmony_ci 13213498266Sopenharmony_ciALLOC_FUNC void *curl_dbg_malloc(size_t wantedsize, 13313498266Sopenharmony_ci int line, const char *source) 13413498266Sopenharmony_ci{ 13513498266Sopenharmony_ci struct memdebug *mem; 13613498266Sopenharmony_ci size_t size; 13713498266Sopenharmony_ci 13813498266Sopenharmony_ci DEBUGASSERT(wantedsize != 0); 13913498266Sopenharmony_ci 14013498266Sopenharmony_ci if(countcheck("malloc", line, source)) 14113498266Sopenharmony_ci return NULL; 14213498266Sopenharmony_ci 14313498266Sopenharmony_ci /* alloc at least 64 bytes */ 14413498266Sopenharmony_ci size = sizeof(struct memdebug) + wantedsize; 14513498266Sopenharmony_ci 14613498266Sopenharmony_ci mem = (Curl_cmalloc)(size); 14713498266Sopenharmony_ci if(mem) { 14813498266Sopenharmony_ci mem->size = wantedsize; 14913498266Sopenharmony_ci } 15013498266Sopenharmony_ci 15113498266Sopenharmony_ci if(source) 15213498266Sopenharmony_ci curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n", 15313498266Sopenharmony_ci source, line, wantedsize, 15413498266Sopenharmony_ci mem ? (void *)mem->mem : (void *)0); 15513498266Sopenharmony_ci 15613498266Sopenharmony_ci return (mem ? mem->mem : NULL); 15713498266Sopenharmony_ci} 15813498266Sopenharmony_ci 15913498266Sopenharmony_ciALLOC_FUNC void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, 16013498266Sopenharmony_ci int line, const char *source) 16113498266Sopenharmony_ci{ 16213498266Sopenharmony_ci struct memdebug *mem; 16313498266Sopenharmony_ci size_t size, user_size; 16413498266Sopenharmony_ci 16513498266Sopenharmony_ci DEBUGASSERT(wanted_elements != 0); 16613498266Sopenharmony_ci DEBUGASSERT(wanted_size != 0); 16713498266Sopenharmony_ci 16813498266Sopenharmony_ci if(countcheck("calloc", line, source)) 16913498266Sopenharmony_ci return NULL; 17013498266Sopenharmony_ci 17113498266Sopenharmony_ci /* alloc at least 64 bytes */ 17213498266Sopenharmony_ci user_size = wanted_size * wanted_elements; 17313498266Sopenharmony_ci size = sizeof(struct memdebug) + user_size; 17413498266Sopenharmony_ci 17513498266Sopenharmony_ci mem = (Curl_ccalloc)(1, size); 17613498266Sopenharmony_ci if(mem) 17713498266Sopenharmony_ci mem->size = user_size; 17813498266Sopenharmony_ci 17913498266Sopenharmony_ci if(source) 18013498266Sopenharmony_ci curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n", 18113498266Sopenharmony_ci source, line, wanted_elements, wanted_size, 18213498266Sopenharmony_ci mem ? (void *)mem->mem : (void *)0); 18313498266Sopenharmony_ci 18413498266Sopenharmony_ci return (mem ? mem->mem : NULL); 18513498266Sopenharmony_ci} 18613498266Sopenharmony_ci 18713498266Sopenharmony_ciALLOC_FUNC char *curl_dbg_strdup(const char *str, 18813498266Sopenharmony_ci int line, const char *source) 18913498266Sopenharmony_ci{ 19013498266Sopenharmony_ci char *mem; 19113498266Sopenharmony_ci size_t len; 19213498266Sopenharmony_ci 19313498266Sopenharmony_ci DEBUGASSERT(str != NULL); 19413498266Sopenharmony_ci 19513498266Sopenharmony_ci if(countcheck("strdup", line, source)) 19613498266Sopenharmony_ci return NULL; 19713498266Sopenharmony_ci 19813498266Sopenharmony_ci len = strlen(str) + 1; 19913498266Sopenharmony_ci 20013498266Sopenharmony_ci mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */ 20113498266Sopenharmony_ci if(mem) 20213498266Sopenharmony_ci memcpy(mem, str, len); 20313498266Sopenharmony_ci 20413498266Sopenharmony_ci if(source) 20513498266Sopenharmony_ci curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n", 20613498266Sopenharmony_ci source, line, (const void *)str, len, (const void *)mem); 20713498266Sopenharmony_ci 20813498266Sopenharmony_ci return mem; 20913498266Sopenharmony_ci} 21013498266Sopenharmony_ci 21113498266Sopenharmony_ci#if defined(_WIN32) && defined(UNICODE) 21213498266Sopenharmony_ciALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str, 21313498266Sopenharmony_ci int line, const char *source) 21413498266Sopenharmony_ci{ 21513498266Sopenharmony_ci wchar_t *mem; 21613498266Sopenharmony_ci size_t wsiz, bsiz; 21713498266Sopenharmony_ci 21813498266Sopenharmony_ci DEBUGASSERT(str != NULL); 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci if(countcheck("wcsdup", line, source)) 22113498266Sopenharmony_ci return NULL; 22213498266Sopenharmony_ci 22313498266Sopenharmony_ci wsiz = wcslen(str) + 1; 22413498266Sopenharmony_ci bsiz = wsiz * sizeof(wchar_t); 22513498266Sopenharmony_ci 22613498266Sopenharmony_ci mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */ 22713498266Sopenharmony_ci if(mem) 22813498266Sopenharmony_ci memcpy(mem, str, bsiz); 22913498266Sopenharmony_ci 23013498266Sopenharmony_ci if(source) 23113498266Sopenharmony_ci curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n", 23213498266Sopenharmony_ci source, line, (void *)str, bsiz, (void *)mem); 23313498266Sopenharmony_ci 23413498266Sopenharmony_ci return mem; 23513498266Sopenharmony_ci} 23613498266Sopenharmony_ci#endif 23713498266Sopenharmony_ci 23813498266Sopenharmony_ci/* We provide a realloc() that accepts a NULL as pointer, which then 23913498266Sopenharmony_ci performs a malloc(). In order to work with ares. */ 24013498266Sopenharmony_civoid *curl_dbg_realloc(void *ptr, size_t wantedsize, 24113498266Sopenharmony_ci int line, const char *source) 24213498266Sopenharmony_ci{ 24313498266Sopenharmony_ci struct memdebug *mem = NULL; 24413498266Sopenharmony_ci 24513498266Sopenharmony_ci size_t size = sizeof(struct memdebug) + wantedsize; 24613498266Sopenharmony_ci 24713498266Sopenharmony_ci DEBUGASSERT(wantedsize != 0); 24813498266Sopenharmony_ci 24913498266Sopenharmony_ci if(countcheck("realloc", line, source)) 25013498266Sopenharmony_ci return NULL; 25113498266Sopenharmony_ci 25213498266Sopenharmony_ci#ifdef __INTEL_COMPILER 25313498266Sopenharmony_ci# pragma warning(push) 25413498266Sopenharmony_ci# pragma warning(disable:1684) 25513498266Sopenharmony_ci /* 1684: conversion from pointer to same-sized integral type */ 25613498266Sopenharmony_ci#endif 25713498266Sopenharmony_ci 25813498266Sopenharmony_ci if(ptr) 25913498266Sopenharmony_ci mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); 26013498266Sopenharmony_ci 26113498266Sopenharmony_ci#ifdef __INTEL_COMPILER 26213498266Sopenharmony_ci# pragma warning(pop) 26313498266Sopenharmony_ci#endif 26413498266Sopenharmony_ci 26513498266Sopenharmony_ci mem = (Curl_crealloc)(mem, size); 26613498266Sopenharmony_ci if(source) 26713498266Sopenharmony_ci curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n", 26813498266Sopenharmony_ci source, line, (void *)ptr, wantedsize, 26913498266Sopenharmony_ci mem ? (void *)mem->mem : (void *)0); 27013498266Sopenharmony_ci 27113498266Sopenharmony_ci if(mem) { 27213498266Sopenharmony_ci mem->size = wantedsize; 27313498266Sopenharmony_ci return mem->mem; 27413498266Sopenharmony_ci } 27513498266Sopenharmony_ci 27613498266Sopenharmony_ci return NULL; 27713498266Sopenharmony_ci} 27813498266Sopenharmony_ci 27913498266Sopenharmony_civoid curl_dbg_free(void *ptr, int line, const char *source) 28013498266Sopenharmony_ci{ 28113498266Sopenharmony_ci if(ptr) { 28213498266Sopenharmony_ci struct memdebug *mem; 28313498266Sopenharmony_ci 28413498266Sopenharmony_ci#ifdef __INTEL_COMPILER 28513498266Sopenharmony_ci# pragma warning(push) 28613498266Sopenharmony_ci# pragma warning(disable:1684) 28713498266Sopenharmony_ci /* 1684: conversion from pointer to same-sized integral type */ 28813498266Sopenharmony_ci#endif 28913498266Sopenharmony_ci 29013498266Sopenharmony_ci mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); 29113498266Sopenharmony_ci 29213498266Sopenharmony_ci#ifdef __INTEL_COMPILER 29313498266Sopenharmony_ci# pragma warning(pop) 29413498266Sopenharmony_ci#endif 29513498266Sopenharmony_ci 29613498266Sopenharmony_ci /* free for real */ 29713498266Sopenharmony_ci (Curl_cfree)(mem); 29813498266Sopenharmony_ci } 29913498266Sopenharmony_ci 30013498266Sopenharmony_ci if(source && ptr) 30113498266Sopenharmony_ci curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr); 30213498266Sopenharmony_ci} 30313498266Sopenharmony_ci 30413498266Sopenharmony_cicurl_socket_t curl_dbg_socket(int domain, int type, int protocol, 30513498266Sopenharmony_ci int line, const char *source) 30613498266Sopenharmony_ci{ 30713498266Sopenharmony_ci curl_socket_t sockfd; 30813498266Sopenharmony_ci 30913498266Sopenharmony_ci if(countcheck("socket", line, source)) 31013498266Sopenharmony_ci return CURL_SOCKET_BAD; 31113498266Sopenharmony_ci 31213498266Sopenharmony_ci sockfd = socket(domain, type, protocol); 31313498266Sopenharmony_ci 31413498266Sopenharmony_ci if(source && (sockfd != CURL_SOCKET_BAD)) 31513498266Sopenharmony_ci curl_dbg_log("FD %s:%d socket() = %" CURL_FORMAT_SOCKET_T "\n", 31613498266Sopenharmony_ci source, line, sockfd); 31713498266Sopenharmony_ci 31813498266Sopenharmony_ci return sockfd; 31913498266Sopenharmony_ci} 32013498266Sopenharmony_ci 32113498266Sopenharmony_ciSEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, 32213498266Sopenharmony_ci SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, 32313498266Sopenharmony_ci SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line, 32413498266Sopenharmony_ci const char *source) 32513498266Sopenharmony_ci{ 32613498266Sopenharmony_ci SEND_TYPE_RETV rc; 32713498266Sopenharmony_ci if(countcheck("send", line, source)) 32813498266Sopenharmony_ci return -1; 32913498266Sopenharmony_ci rc = send(sockfd, buf, len, flags); 33013498266Sopenharmony_ci if(source) 33113498266Sopenharmony_ci curl_dbg_log("SEND %s:%d send(%lu) = %ld\n", 33213498266Sopenharmony_ci source, line, (unsigned long)len, (long)rc); 33313498266Sopenharmony_ci return rc; 33413498266Sopenharmony_ci} 33513498266Sopenharmony_ci 33613498266Sopenharmony_ciRECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, 33713498266Sopenharmony_ci RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line, 33813498266Sopenharmony_ci const char *source) 33913498266Sopenharmony_ci{ 34013498266Sopenharmony_ci RECV_TYPE_RETV rc; 34113498266Sopenharmony_ci if(countcheck("recv", line, source)) 34213498266Sopenharmony_ci return -1; 34313498266Sopenharmony_ci rc = recv(sockfd, buf, len, flags); 34413498266Sopenharmony_ci if(source) 34513498266Sopenharmony_ci curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n", 34613498266Sopenharmony_ci source, line, (unsigned long)len, (long)rc); 34713498266Sopenharmony_ci return rc; 34813498266Sopenharmony_ci} 34913498266Sopenharmony_ci 35013498266Sopenharmony_ci#ifdef HAVE_SOCKETPAIR 35113498266Sopenharmony_ciint curl_dbg_socketpair(int domain, int type, int protocol, 35213498266Sopenharmony_ci curl_socket_t socket_vector[2], 35313498266Sopenharmony_ci int line, const char *source) 35413498266Sopenharmony_ci{ 35513498266Sopenharmony_ci int res = socketpair(domain, type, protocol, socket_vector); 35613498266Sopenharmony_ci 35713498266Sopenharmony_ci if(source && (0 == res)) 35813498266Sopenharmony_ci curl_dbg_log("FD %s:%d socketpair() = " 35913498266Sopenharmony_ci "%" CURL_FORMAT_SOCKET_T " %" CURL_FORMAT_SOCKET_T "\n", 36013498266Sopenharmony_ci source, line, socket_vector[0], socket_vector[1]); 36113498266Sopenharmony_ci 36213498266Sopenharmony_ci return res; 36313498266Sopenharmony_ci} 36413498266Sopenharmony_ci#endif 36513498266Sopenharmony_ci 36613498266Sopenharmony_cicurl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, 36713498266Sopenharmony_ci int line, const char *source) 36813498266Sopenharmony_ci{ 36913498266Sopenharmony_ci struct sockaddr *addr = (struct sockaddr *)saddr; 37013498266Sopenharmony_ci curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; 37113498266Sopenharmony_ci 37213498266Sopenharmony_ci curl_socket_t sockfd = accept(s, addr, addrlen); 37313498266Sopenharmony_ci 37413498266Sopenharmony_ci if(source && (sockfd != CURL_SOCKET_BAD)) 37513498266Sopenharmony_ci curl_dbg_log("FD %s:%d accept() = %" CURL_FORMAT_SOCKET_T "\n", 37613498266Sopenharmony_ci source, line, sockfd); 37713498266Sopenharmony_ci 37813498266Sopenharmony_ci return sockfd; 37913498266Sopenharmony_ci} 38013498266Sopenharmony_ci 38113498266Sopenharmony_ci/* separate function to allow libcurl to mark a "faked" close */ 38213498266Sopenharmony_civoid curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) 38313498266Sopenharmony_ci{ 38413498266Sopenharmony_ci if(source) 38513498266Sopenharmony_ci curl_dbg_log("FD %s:%d sclose(%" CURL_FORMAT_SOCKET_T ")\n", 38613498266Sopenharmony_ci source, line, sockfd); 38713498266Sopenharmony_ci} 38813498266Sopenharmony_ci 38913498266Sopenharmony_ci/* this is our own defined way to close sockets on *ALL* platforms */ 39013498266Sopenharmony_ciint curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) 39113498266Sopenharmony_ci{ 39213498266Sopenharmony_ci int res = sclose(sockfd); 39313498266Sopenharmony_ci curl_dbg_mark_sclose(sockfd, line, source); 39413498266Sopenharmony_ci return res; 39513498266Sopenharmony_ci} 39613498266Sopenharmony_ci 39713498266Sopenharmony_ciALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode, 39813498266Sopenharmony_ci int line, const char *source) 39913498266Sopenharmony_ci{ 40013498266Sopenharmony_ci FILE *res = fopen(file, mode); 40113498266Sopenharmony_ci 40213498266Sopenharmony_ci if(source) 40313498266Sopenharmony_ci curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", 40413498266Sopenharmony_ci source, line, file, mode, (void *)res); 40513498266Sopenharmony_ci 40613498266Sopenharmony_ci return res; 40713498266Sopenharmony_ci} 40813498266Sopenharmony_ci 40913498266Sopenharmony_ciALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode, 41013498266Sopenharmony_ci int line, const char *source) 41113498266Sopenharmony_ci{ 41213498266Sopenharmony_ci FILE *res = fdopen(filedes, mode); 41313498266Sopenharmony_ci if(source) 41413498266Sopenharmony_ci curl_dbg_log("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n", 41513498266Sopenharmony_ci source, line, filedes, mode, (void *)res); 41613498266Sopenharmony_ci return res; 41713498266Sopenharmony_ci} 41813498266Sopenharmony_ci 41913498266Sopenharmony_ciint curl_dbg_fclose(FILE *file, int line, const char *source) 42013498266Sopenharmony_ci{ 42113498266Sopenharmony_ci int res; 42213498266Sopenharmony_ci 42313498266Sopenharmony_ci DEBUGASSERT(file != NULL); 42413498266Sopenharmony_ci 42513498266Sopenharmony_ci if(source) 42613498266Sopenharmony_ci curl_dbg_log("FILE %s:%d fclose(%p)\n", 42713498266Sopenharmony_ci source, line, (void *)file); 42813498266Sopenharmony_ci 42913498266Sopenharmony_ci res = fclose(file); 43013498266Sopenharmony_ci 43113498266Sopenharmony_ci return res; 43213498266Sopenharmony_ci} 43313498266Sopenharmony_ci 43413498266Sopenharmony_ci#define LOGLINE_BUFSIZE 1024 43513498266Sopenharmony_ci 43613498266Sopenharmony_ci/* this does the writing to the memory tracking log file */ 43713498266Sopenharmony_civoid curl_dbg_log(const char *format, ...) 43813498266Sopenharmony_ci{ 43913498266Sopenharmony_ci char *buf; 44013498266Sopenharmony_ci int nchars; 44113498266Sopenharmony_ci va_list ap; 44213498266Sopenharmony_ci 44313498266Sopenharmony_ci if(!curl_dbg_logfile) 44413498266Sopenharmony_ci return; 44513498266Sopenharmony_ci 44613498266Sopenharmony_ci buf = (Curl_cmalloc)(LOGLINE_BUFSIZE); 44713498266Sopenharmony_ci if(!buf) 44813498266Sopenharmony_ci return; 44913498266Sopenharmony_ci 45013498266Sopenharmony_ci va_start(ap, format); 45113498266Sopenharmony_ci nchars = mvsnprintf(buf, LOGLINE_BUFSIZE, format, ap); 45213498266Sopenharmony_ci va_end(ap); 45313498266Sopenharmony_ci 45413498266Sopenharmony_ci if(nchars > LOGLINE_BUFSIZE - 1) 45513498266Sopenharmony_ci nchars = LOGLINE_BUFSIZE - 1; 45613498266Sopenharmony_ci 45713498266Sopenharmony_ci if(nchars > 0) 45813498266Sopenharmony_ci fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile); 45913498266Sopenharmony_ci 46013498266Sopenharmony_ci (Curl_cfree)(buf); 46113498266Sopenharmony_ci} 46213498266Sopenharmony_ci 46313498266Sopenharmony_ci#endif /* CURLDEBUG */ 464