Put all allocation functions into dispatch table.
Implement these new functions for all of the debug malloc types.
Fix a number of bugs in the debug malloc functions related to overflow
conditions.
Fix a bug in dlpvalloc due to an overflow condition.
Fix various other bugs in the debug malloc functions.
Add new tests for malloc functions.
Bug: 11225066
Change-Id: Idf50f389603e2157645565bc15cd9365eec2e9dd
diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp
index aa7c072..2cc38cc 100644
--- a/libc/bionic/malloc_debug_leak.cpp
+++ b/libc/bionic/malloc_debug_leak.cpp
@@ -250,6 +250,33 @@
return Malloc(malloc_usable_size)(mem);
}
+extern "C" struct mallinfo fill_mallinfo() {
+ return Malloc(mallinfo)();
+}
+
+extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) {
+ if ((alignment & (alignment - 1)) != 0) {
+ return EINVAL;
+ }
+ int saved_errno = errno;
+ *memptr = fill_memalign(alignment, size);
+ errno = saved_errno;
+ return (*memptr != NULL) ? 0 : ENOMEM;
+}
+
+extern "C" void* fill_pvalloc(size_t bytes) {
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+ size_t size = (bytes + pagesize - 1) & ~(pagesize - 1);
+ if (size < bytes) { // Overflow
+ return NULL;
+ }
+ return fill_memalign(pagesize, size);
+}
+
+extern "C" void* fill_valloc(size_t size) {
+ return fill_memalign(sysconf(_SC_PAGESIZE), size);
+}
+
// =============================================================================
// malloc leak functions
// =============================================================================
@@ -265,6 +292,7 @@
size_t size = bytes + sizeof(AllocationEntry);
if (size < bytes) { // Overflow.
+ errno = ENOMEM;
return NULL;
}
@@ -327,6 +355,7 @@
// Fail on overflow - just to be safe even though this code runs only
// within the debugging C library, not the production one.
if (n_elements && SIZE_MAX / n_elements < elem_size) {
+ errno = ENOMEM;
return NULL;
}
size_t size = n_elements * elem_size;
@@ -350,6 +379,7 @@
} else if (header->guard != GUARD) {
debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
header->guard, header->entry);
+ errno = ENOMEM;
return NULL;
}
@@ -358,8 +388,8 @@
size_t oldSize = header->entry->size & ~SIZE_FLAG_MASK;
size_t copySize = (oldSize <= bytes) ? oldSize : bytes;
memcpy(newMem, oldMem, copySize);
+ leak_free(oldMem);
}
- leak_free(oldMem);
return newMem;
}
@@ -428,3 +458,30 @@
}
return 0;
}
+
+extern "C" struct mallinfo leak_mallinfo() {
+ return Malloc(mallinfo)();
+}
+
+extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) {
+ if ((alignment & (alignment - 1)) != 0) {
+ return EINVAL;
+ }
+ int saved_errno = errno;
+ *memptr = leak_memalign(alignment, size);
+ errno = saved_errno;
+ return (*memptr != NULL) ? 0 : ENOMEM;
+}
+
+extern "C" void* leak_pvalloc(size_t bytes) {
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+ size_t size = (bytes + pagesize - 1) & ~(pagesize - 1);
+ if (size < bytes) { // Overflow
+ return NULL;
+ }
+ return leak_memalign(pagesize, size);
+}
+
+extern "C" void* leak_valloc(size_t size) {
+ return leak_memalign(sysconf(_SC_PAGESIZE), size);
+}