[En-Nut-Discussion] File descriptor leak in 4.8.7
Stefan Hax
stefan at escherlogic.com
Wed May 6 16:07:15 CEST 2015
You don't seem to be doing anything for a non-0 return from
NutTcpAccept(). Try something simple like:
while(NutTcpAccept(sock, 80));
since NutTcpAccept calls NutTcpStatePassiveOpenEvent etc.. follow the code..
Stefan.
On 2015-05-06 9:14 AM, Coleman Brumley wrote:
> 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
>>>
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
More information about the En-Nut-Discussion
mailing list