[En-Nut-Discussion] File descriptor leak in 4.8.7

Coleman Brumley cbrumley at polarsoft.biz
Wed May 6 15:14:26 CEST 2015


Hi Henrik,

That's originally what I was thinking and why I restructured the code
differently from the example, so I knew that the call to being made to
NutTcpCloseSocket explicitly. Here's my updated HTTP thread code. It does
close the socket if the stream returned from _fdopen is NULL. Since adding
the mutex, _fdopen no longer fails at all. 

THREAD(Service, arg)
{
    TCPSOCKET *sock;
    FILE *stream;
    u_char id = (u_char) ((uptr_t) arg);
    u_char timeout=0;
    u_long ul = 1000;      
    time_t t;
    struct _tm tmx ;
   uint16_t lowheapcounter=1000;
    NutThreadSetPriority(72);	


    /*
     * Now loop endless for connections.
     */

    for (;;) {

        /*
         * Create a socket.
         */
	if ((sock = NutTcpCreateSocket()) == 0) 
	{
		printf("[%u] Creating socket failed\n", id);
		NutSleep(5000);
		continue;
	}
	NutTcpSetSockOpt (sock, SO_SNDTIMEO, &ul, sizeof(ul));
	NutTcpSetSockOpt(sock, SO_RCVTIMEO, &ul, sizeof(ul));           
        /*
         * Listen on port 80. This call will block until we get a connection
         * from a client.
         */

#ifdef REL_VERSION
        NutTcpAccept(sock, 80);
#else
        NutTcpAccept(sock, 8080);

#endif
	NutMutexLock(&httpSessionMutex);
        /*
         * Wait until at least 4 kByte of free RAM is available. This will
         * keep the client connected in low memory situations.
         */
		while (NutHeapAvailable() < 4096) {
			t=time(0l);
			localtime_r(&t,&tmx);
			printf("%02d:%02d:%02d %02d-%02d-%04d -- ",
				tmx.tm_hour,
				tmx.tm_min,
				tmx.tm_sec,
				tmx.tm_mon+1,
				tmx.tm_mday,
				tmx.tm_year+1900);
			printf("[%u] Low mem (%d)\n", id,
(int)NutHeapAvailable());
			NutSleep(1000);
			lowheapcounter--;
			if(lowheapcounter<=0) Hreset();
		}

        /*
         * Associate a stream with the socket so we can use standard I/O
calls.
         */
		
		while (((stream = _fdopen((int) ((uptr_t) sock), "r+b")) ==
0)&&(++timeout<0xFF)) 
		{
           			 NutSleep(10);
		} 
		if(!stream)
		{
			printf("\n[%u] Creating stream device failed w/
errno:%d\n", id,errno);
			NutTcpCloseSocket(sock);
			NutMutexUnlock(&httpSessionMutex);
			continue;
		}
		else
		{         
		            NutHttpProcessRequest(stream);            
		            fclose(stream);
		           NutTcpCloseSocket(sock);
		          NutMutexUnlock(&httpSessionMutex);
        		}
    	}
}
Coleman

> -----Original Message-----
> From: Henrik Maier [mailto:hmnews at proconx.com]
> Sent: Tuesday, May 05, 2015 8:05 PM
> To: cbrumley at polarsoft.biz; Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] File descriptor leak in 4.8.7
> 
> Hi Coleman,
> 
> Could the memory leak be caused by not closing the socket when _fdopen
> fails?
> 
> Henrik
> 
> 
> On 5/05/2015 7:47 AM, Coleman Brumley wrote:
> > After doing some arithmetic, it appears that each occurrence of
> > "Creating stream device failed" causes a 1271 byte leak from heap
> > space. Does that number ring a bell?
> >
> >
> >
> > I've re-verified that this does not happen unless a browser is making
> > HTTP requests of the controller. If the controller is just "sitting
> > there", there is no leak. I verify this via a printout of available
> > heap space every 30 minutes. After running for 4 hours, there were no
> leaks.
> >
> >
> >
> > While there is no set time between each occurrence, this does seem to
> > happen about 5 times in 30 minutes.
> >
> >
> >
> > The errno value 23 means that too many files are open, correct?
> > FOPEN_MAX is defined as 8, so is having six concurrent HTTP threads
> > running too many? Is it possible that the use of multiple HTTP threads
> > without using a mutex is causing the file open handles to corrupt
> > somehow and therefore not be closed correctly?
> >
> >
> >
> > Coleman
> >
> >
> >
> > From: Coleman Brumley [mailto:cbrumley at polarsoft.biz]
> > Sent: Monday, May 04, 2015 1:19 PM
> > To: en-nut-discussion at egnite.de
> > Subject: File descriptor leak in 4.8.7
> >
> >
> >
> > Everyone,
> >
> >
> >
> > I'm working with Nut/OS v4.8.7 (for many, many reasons, I CANNOT
> > upgrade the core OS). The processor is an Atmel SAM7X256.
> >
> >
> >
> > I'm encountering a problem with the use of file descriptors in HTTP,
> > and I believe the core effect is a resource leak.
> >
> >
> >
> > Here is my HTTP service code:
> >
> >
> >
> > THREAD(Service, arg)
> >
> > {
> >
> >         TCPSOCKET *sock;
> >
> >         FILE *stream;
> >
> >         u_char id = (u_char) ((uptr_t) arg);
> >
> >        u_char timeout=0;
> >
> >         time_t t;
> >
> >         struct _tm tmx ;
> >
> >         uint16_t lowheapcounter=1000;
> >
> > NutThreadSetPriority(72);
> >
> >
> >
> >      /*
> >
> >       * Now loop endless for connections.
> >
> >       */
> >
> >
> >
> >      for (;;) {
> >
> >
> >
> >          /*
> >
> >           * Create a socket.
> >
> >           */
> >
> >                if ((sock = NutTcpCreateSocket()) == 0)
> >
> >                {
> >
> >                       printf("[%u] Creating socket failed\n", id);
> >
> >                       NutSleep(5000);
> >
> >                       continue;
> >
> >                }
> >
> >          /*
> >
> >           * Listen on port 80. This call will block until we get a
> > connection
> >
> >           * from a client.
> >
> >           */
> >
> >          NutTcpAccept(sock, 80);
> >
> >
> >
> >
> >
> >          /*
> >
> >           * Detect low heap and if it happens for too long, reset.
> >
> >           *
> >
> >           */
> >
> >                while (NutHeapAvailable() < 4096) {
> >
> >                       t=time(0l);
> >
> >                       localtime_r(&t,&tmx);
> >
> >                       printf("%02d:%02d:%02d %02d-%02d-%04d -- ",
> >
> >                             tmx.tm_hour,
> >
> >                             tmx.tm_min,
> >
> >                             tmx.tm_sec,
> >
> >                             tmx.tm_mon+1,
> >
> >                             tmx.tm_mday,
> >
> >                             tmx.tm_year+1900);
> >
> >                       printf("[%u] Low mem (%d)\n", id,
> > (int)NutHeapAvailable());
> >
> >                       NutSleep(1000);
> >
> >                       lowheapcounter--;
> >
> >                       if(lowheapcounter<=0) Hreset();
> >
> >                }
> >
> >
> >
> >          /*
> >
> >           * Associate a stream with the socket so we can use standard
> > I/O calls.
> >
> >           */
> >
> >
> >
> >                while (((stream = _fdopen((int) ((uptr_t) sock),
> > "r+b")) ==
> > 0)&&(++timeout<0xFF))
> >
> >                {
> >
> >                       NutSleep(10);
> >
> >                }
> >
> >                if(!stream)
> >
> >                {
> >
> >                       printf("\n[%u] Creating stream device failed w/
> > errno:%d\n", id,errno);
> >
> > NutTcpCloseSocket(sock);
> >
> >                       continue;
> >
> >                }
> >
> >                else
> >
> >                {
> >
> >                       NutHttpProcessRequest(stream);
> >
> >                       fclose(stream);
> >
> >                       NutTcpCloseSocket(sock);
> >
> >                }
> >
> >      }
> >
> > }
> >
> >
> >
> > The console output shows all is normal initially, but after a while
(approx.
> > 765 seconds, initially after boot time) I start seeing"
> >
> >
> >
> > [3] Creating stream device failed w/ errno:23
> >
> >
> >
> > Where the number in braces is the thread id. I'm running 6 HTTP
> > threads, started as follows:
> >
> > for (i = 1; i <= 6; i++)
> >
> > {
> >
> > char thname[] = "httpd0";
> >
> >          thname[5] = '0' + i;
> >
> >          NutThreadCreate(thname, Service, (void *) (uptr_t)
> > i,HTTPD_SERVICE_STACK);
> >
> > }
> >
> >
> >
> > The stack size is defined as 1024.
> >
> >
> >
> > I noticed this question was asked some time ago on this list, but I
> > could not determine if there was ever a solution posted. There are
> > other I/O processes running in the controller, but it ONLY runs low on
> > resources when a browser is connected to it.
> >
> >
> >
> > Does anyone have any suggestions as to what I could look into as to
> > what might be the problem?
> >
> >
> >
> > While the browser(s) are connected, the system appears to lose about
> > 4.5k of heap space per 30 minutes!
> >
> >
> >
> > Thanks in advance.
> >
> >
> >
> > Best Regards,
> >
> > Coleman
> >
> > _______________________________________________
> > http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> >




More information about the En-Nut-Discussion mailing list