diff options
| author | Christopher Ferris <cferris@google.com> | 2014-06-09 19:14:11 -0700 |
|---|---|---|
| committer | Christopher Ferris <cferris@google.com> | 2014-06-12 15:08:18 -0700 |
| commit | a403780538ac9d1a260e064df6599663f8cc4166 (patch) | |
| tree | 340dd81279be34b49622c68dc037ceb5cd73bcc9 /libc/bionic/malloc_debug_leak.cpp | |
| parent | 0ada9388e74693d990bdbb4af92c33bae8b34d4b (diff) | |
| download | bionic-a403780538ac9d1a260e064df6599663f8cc4166.zip bionic-a403780538ac9d1a260e064df6599663f8cc4166.tar.gz bionic-a403780538ac9d1a260e064df6599663f8cc4166.tar.bz2 | |
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
Diffstat (limited to 'libc/bionic/malloc_debug_leak.cpp')
| -rw-r--r-- | libc/bionic/malloc_debug_leak.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
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 @@ 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); +} |
