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
This commit is contained in:
Christopher Ferris
2014-06-09 19:14:11 -07:00
parent 0ada9388e7
commit a403780538
7 changed files with 698 additions and 451 deletions

View File

@@ -250,6 +250,33 @@ extern "C" size_t fill_malloc_usable_size(const void* mem) {
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 @@ extern "C" void* leak_malloc(size_t bytes) {
size_t size = bytes + sizeof(AllocationEntry);
if (size < bytes) { // Overflow.
errno = ENOMEM;
return NULL;
}
@@ -327,6 +355,7 @@ extern "C" void* leak_calloc(size_t n_elements, size_t elem_size) {
// 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 @@ extern "C" void* leak_realloc(void* oldMem, size_t bytes) {
} 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 @@ extern "C" void* leak_realloc(void* oldMem, size_t bytes) {
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 @@ extern "C" size_t leak_malloc_usable_size(const void* mem) {
}
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);
}