Search code examples
cheap-memorysyslog

Writing to syslog causes heap allocation to steadily increase in size


Yesterday I was wondering why the number of allocs and frees on the heap kept creeping up: Valgrind understanding bytes allocated increase in heap summary?

Today I have found the culprit, however I do not understand why:

openlog ("XYSV", LOG_PID, LOG_SYSLOG);
syslog (LOG_NOTICE, "server started by %s(%d) on port %d", getenv("USER"),getuid (),servPort);
closelog();

for (;;) /* Run forever */
{
    clntSock = AcceptTCPConnection(servSock);
    char ipstr[INET6_ADDRSTRLEN];

    /* Fork child process and report any errors */
    if ((processID = fork()) < 0)
        DieWithError("fork() failed");
    else if (processID == 0)  /* If this is the child process */
    {
        close(servSock);   /* Child closes parent socket */
        HandleTCPClient(clntSock);

        exit(0);           /* Child process terminates */
    }

    openlog ("XYSV", LOG_PID, LOG_SYSLOG);
    //syslog(LOG_INFO,"%d : created new child process for connect from %s\n", (int) processID,ipstr);
    //syslog(LOG_INFO, "test");
    closelog();

    close(clntSock);       /* Parent closes child socket descriptor */
    childProcCount++;      /* Increment number of outstanding child processes */    
}

As soon as I uncomment the two syslog entries the allocs on the heap (reported by Valgrind) keep increasing. The allocs are also freed, however the total number of allocs keeps increasing and thus the size of the allocated memory. IMHO this would sooner or later cause the server to run out of mem.

My question is: why would this write to the syslog cause the allocs to increase. I am closing the syslog nicely. The first syslog does not have an effect on the heap allocation. When I leave the open and close in place for the second write to the syslog and leave the actual write commented out everything is allright. As soon as I uncomment one or two of the syslog lines the allocs start creeping up.

I must be overseeing something obvious.


Solution

  • The syslog call will allocate memory to hold the log message before delivering it if the message is larger than its local buffer.

    It actually writes to a FILE * that was created by a call to open_memstream, which is a C file stream that actually uses a buffer that is automatically grown as required. It then takes the buffer and sends its contents to the logger.

    Source is here.