This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
malloc could leak memory
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: newlib at sources dot redhat dot com
- Date: 13 Apr 2002 07:17:44 -0300
- Subject: malloc could leak memory
- Organization: GCC Team, Red Hat
In the unlikely case of failure of the sbrk() that attempts to align
the sbrk to a page boundary, we'd leak the whole chunk of memory
previously allocated. This patch corrects this problem, by leaving
the top of the heap misaligned and attempting to correct it next
time. I'm checking this in, approved by Jeff Johnston.
Index: newlib/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* libc/stdlib/mallocr.c (malloc_extend_top): If correction sbrk
fails, don't bail out, and try to correct next time.
Index: newlib/libc/stdlib/mallocr.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/mallocr.c,v
retrieving revision 1.5
diff -u -p -r1.5 mallocr.c
--- newlib/libc/stdlib/mallocr.c 3 Feb 2002 09:24:14 -0000 1.5
+++ newlib/libc/stdlib/mallocr.c 13 Apr 2002 10:19:57 -0000
@@ -2128,6 +2128,7 @@ static void malloc_extend_top(RARG nb) R
char* brk; /* return value from sbrk */
INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
INTERNAL_SIZE_T correction; /* bytes for 2nd sbrk call */
+ int correction_failed = 0; /* whether we should relax the assertion */
char* new_brk; /* return of 2nd sbrk call */
INTERNAL_SIZE_T top_size; /* new size of top chunk */
@@ -2152,11 +2153,13 @@ static void malloc_extend_top(RARG nb) R
/* Fail if sbrk failed or if a foreign sbrk call killed our space */
if (brk == (char*)(MORECORE_FAILURE) ||
(brk < old_end && old_top != initial_top))
- return;
+ return;
sbrked_mem += sbrk_size;
- if (brk == old_end) /* can just add bytes to current top */
+ if (brk == old_end /* can just add bytes to current top, unless
+ previous correction failed */
+ && ((POINTER_UINT)old_end & (pagesz - 1)) == 0)
{
top_size = sbrk_size + old_top_size;
set_head(top, top_size | PREV_INUSE);
@@ -2183,7 +2186,12 @@ static void malloc_extend_top(RARG nb) R
/* Allocate correction */
new_brk = (char*)(MORECORE (correction));
- if (new_brk == (char*)(MORECORE_FAILURE)) return;
+ if (new_brk == (char*)(MORECORE_FAILURE))
+ {
+ correction = 0;
+ correction_failed = 1;
+ new_brk = brk;
+ }
sbrked_mem += correction;
@@ -2228,7 +2236,8 @@ static void malloc_extend_top(RARG nb) R
#endif
/* We always land on a page boundary */
- assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
+ assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0
+ || correction_failed);
}
#endif /* DEFINE_MALLOC */
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer