httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Slemko <>
Subject Memory leak in accept(), Solaris 2.5.1 (fwd)
Date Wed, 24 Sep 1997 03:52:56 GMT
Interesting.  If true, another reason to use serialized accepts.

---------- Forwarded message ----------
>From: (Mike Gleason, remove the FIXTHIS)
>Newsgroups: comp.unix.solaris
>Subject: Memory leak in accept(), Solaris 2.5.1
>Date: Wed, 24 Sep 1997 02:49:02 GMT
>Organization: NCEMRSoft
>Lines: 157
>Message-ID: <>
>X-Newsreader: Forte Free Agent 1.11/32.235
>Xref: comp.unix.solaris:117796    

I have found a memory leak that affects Solaris 2.5.1 (Intel and
Sparc, with the Sept 17 recommended patch cluster applied) when the
accept() socket library function is used.  Memory is leaked when an
alarm causes accept() to jump out of the function, without free()ing
memory malloc()'d by accept().

Perhaps someone could point me to an official method of reporting
this.  I'm not a contract customer and I couldn't find anything on the
Sun webs.

Example code (stripped bare for brevity) is next, followed by output
showing how the leak occurs.  Unfortunately for TCP/IP servers, this
can cause a long-running daemon process to consume all swap space and
grind the machine to a halt.

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>

char mallbuf[1024 * 100];
char *mbptr;
jmp_buf jmp;

void *
malloc(size_t n)
        static int calls = 0;
        char *p;
        char m[64];

        if (calls++ == 0) {
                mbptr = mallbuf;

        p = mbptr;
        if ((n % 8) == 0)
                mbptr += n;
                mbptr += n + (8 - (n % 8));

        write(1, "used malloc\n", 12);
        return (p);
}       /* malloc */

free(void *p)
        write(1, "used free  \n", 12);
}       /* free */

static void
hdlr(int num)
        longjmp(jmp, 1);
}       /* hdlr */

main(int argc, char **argv)
        int s, s2, addrsize;
        struct sockaddr_in addr;
        unsigned short port;

        if (argc < 2) exit(2);
        port = (unsigned short) atoi(argv[1]);

        write(1, "socket\n", 7);
        s = socket(AF_INET, SOCK_STREAM, 0);

        (void) memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons(port);
        write(1, "bind  \n", 7);
        bind(s, &addr, sizeof(addr));

        write(1, "listen\n", 7);
        listen(s, 2);

        for (;;) {
                if (setjmp(jmp) != 0) {
                        write (1, "accept timeout\n", 15);
                signal(SIGALRM, hdlr);
                (void) memset(&addr, 0, sizeof(addr));
                addrsize = sizeof(addr);
                write(1, "accept\n", 7);
                s2 = accept(s, &addr, &addrsize);
                if (s2 >= 0) {
                        write (1, "accept okay   \n", 15);
                } else {
                        write (1, "accept error  \n", 15);

        write(1, "done\n", 5);

Output follows.  Note how malloc() isn't called until the second time
accept is used.

21 Avalanche ~/src > a.out 5102
used malloc
used malloc
used free  
accept timeout
used malloc
accept timeout
used malloc
accept timeout
used malloc


select() can be used as a timeout mechanism, instead of using alarm().


I've spent three months trying to track down this bug.  I also had to
purchase a separate machine and Solaris license on which to load test
an app on a Solaris platform.  Although normally that wouldn't be
necessary, it's still tough for a small, independent developer to
support Sun operating systems.  I'd happily take a copy of the Sun C
compiler for Intel in exchange for all the resources I had to exhaust
on this one so I wouldn't have to use gcc atleast.

~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mike Gleason, NCEMRSoft. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
(Please remove the "FIXTHIS" from my email address before replying.)
ObPlug:  Try NcFTPd ( instead of wu-ftpd!

View raw message