memdebug: buffer output data

Instead of writing each line to file immediately, this now stores them
in an in-memory buffer until that gets full or curl exits. To make it
run faster and write to file less often.

Closes #19750
This commit is contained in:
Daniel Stenberg 2025-11-28 17:16:31 +01:00
parent d73efc62c1
commit 06e16167d6
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -62,6 +62,10 @@ static long memsize = 0; /* set number of mallocs allowed */
static struct backtrace_state *btstate;
#endif
#define KEEPSIZE 10000
static char membuf[KEEPSIZE];
static size_t memwidx = 0; /* write index */
/* LeakSantizier (LSAN) calls _exit() instead of exit() when a leak is detected
on exit so the logfile must be closed explicitly or data could be lost.
Though _exit() does not call atexit handlers such as this, LSAN's call to
@ -71,6 +75,8 @@ static void curl_dbg_cleanup(void)
if(curl_dbg_logfile &&
curl_dbg_logfile != stderr &&
curl_dbg_logfile != stdout) {
if(memwidx)
fwrite(membuf, 1, memwidx, curl_dbg_logfile);
/* !checksrc! disable BANNEDFUNC 1 */
fclose(curl_dbg_logfile);
}
@ -506,7 +512,7 @@ int curl_dbg_fclose(FILE *file, int line, const char *source)
void curl_dbg_log(const char *format, ...)
{
char buf[1024];
int nchars;
size_t nchars;
va_list ap;
if(!curl_dbg_logfile)
@ -519,8 +525,20 @@ void curl_dbg_log(const char *format, ...)
if(nchars > (int)sizeof(buf) - 1)
nchars = (int)sizeof(buf) - 1;
if(nchars > 0)
fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile);
if(nchars > 0) {
if(KEEPSIZE - nchars < memwidx) {
/* flush */
fwrite(membuf, 1, memwidx, curl_dbg_logfile);
fflush(curl_dbg_logfile);
memwidx = 0;
}
if(memwidx) {
/* the previous line ends with a newline */
DEBUGASSERT(membuf[memwidx - 1] == '\n');
}
memcpy(&membuf[memwidx], buf, nchars);
memwidx += nchars;
}
}
#endif /* CURLDEBUG */