svn commit: branches/uClibc_0_9_29/libc/unistd

vapier at uclibc.org vapier at uclibc.org
Sat Jan 5 17:57:58 UTC 2008


Author: vapier
Date: 2008-01-05 09:57:57 -0800 (Sat, 05 Jan 2008)
New Revision: 20795

Log:
Merge r20665 by vapier from trunk:
plug a memory leak when using execl* functions on no-mmu


Modified:
   branches/uClibc_0_9_29/libc/unistd/exec.c


Changeset:
Modified: branches/uClibc_0_9_29/libc/unistd/exec.c
===================================================================
--- branches/uClibc_0_9_29/libc/unistd/exec.c	2008-01-05 17:57:46 UTC (rev 20794)
+++ branches/uClibc_0_9_29/libc/unistd/exec.c	2008-01-05 17:57:57 UTC (rev 20795)
@@ -56,7 +56,9 @@
 /* We do not have an MMU, so using alloca() is not an option.
  * Less obviously, using malloc() is not an option either since
  * malloc()ed memory can leak in a vfork() and exec*() situation.
- * Therefore, we must use mmap() and unmap() directly.
+ * Therefore, we must use mmap() and unmap() directly, caching
+ * the result as we go.  This way we minimize the leak to 1
+ * allocation.
  */
 
 # define EXEC_ALLOC_SIZE(VAR)	size_t VAR;	/* Semicolon included! */
@@ -68,22 +70,28 @@
 
 # ifdef L___exec_alloc
 
+void attribute_hidden __exec_free(void *ptr, size_t size)
+{
+	if (ptr)
+		munmap(ptr, size);
+}
+
 void attribute_hidden *__exec_alloc(size_t size)
 {
-	void *p;
+	static void *p;
+	static size_t old_size;
 
+	if (old_size >= size)
+		return p;
+	else
+		__exec_free(p, old_size);
+
+	old_size = size;
 	p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
 
 	return (p != MAP_FAILED) ? p : NULL;
 }
 
-void attribute_hidden __exec_free(void *ptr, size_t size)
-{
-	if (ptr) {
-		munmap(ptr, size);
-	}
-}
-
 # endif
 
 #endif




More information about the uClibc-cvs mailing list