[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