possible memory leak in newlib 1.11.0

J. Johnston jjohnstn@redhat.com
Tue Oct 28 05:33:00 GMT 2003


Joel Sherrill wrote:
> 
> Hi,
> 
> An RTEMS user has discovered a memory leak with newlib 1.11.0. Under
> RTEMS, each thread is given a reentrancy structure.  It is malloc'ed
> at thread create and free'ed when the thread is deleted.  No leaks
> are evident until the task does a printf().  This results in
> the following code around line 81 of stdio/makebuf.c being executed:
> 
>   if ((p = _malloc_r (fp->_data, size)) == NULL)
>     {
>       fp->_flags |= __SNBF;
>       fp->_bf._base = fp->_p = fp->_nbuf;
>       fp->_bf._size = 1;
>     }
>   else
>     {
>       fp->_data->__cleanup = _cleanup_r;
>       fp->_flags |= __SMBF;
>       fp->_bf._base = fp->_p = (unsigned char *) p;
> 
> So in this case stdout->_data is malloc'ed memory.
> 
> At thread deletion, RTEMS does this which we assumed
> would have taken care of tearing down all the structures
> and buffers in the reentrancy structure.
> 
>     _wrapup_reent(ptr);
>     _reclaim_reent(ptr);
>     free(ptr);
> 
> This results in the above malloc'ed buffer (1K) being lost.
> I added this hack in our thread delete code which fixes it:
> 
> int newlib_free_buffers(   FILE *fp ) {
>   if (fp->_flags & __SMBF) {
>     free( fp->_bf._base );
>     fp->_flags &= ~__SMBF;
>     fp->_bf._base = fp->_p = (unsigned char *) NULL;
>   }
>   return 0;
> }
> 
> _fwalk(ptr, newlib_free_buffers);
> 
> Where should this memory be freed?  What should be done to make sure
> this buffer gets deallocated?
> 

I noticed this in libc/stdio/findfp.c:

void
_cleanup_r (ptr)
      struct _reent *ptr;
{
   /* (void) _fwalk(fclose); */
   (void) _fwalk (ptr, fflush);  /* `cheating' */
}

If _cleanup_r does the fclose walk, the problem is handled automatically.

-- Jeff J.





More information about the Newlib mailing list