Merge "Use libunwindbacktrace for debug malloc code."
This commit is contained in:
commit
4ad5066e1d
@ -980,8 +980,6 @@ LOCAL_SRC_FILES := \
|
||||
$(libc_arch_dynamic_src_files) \
|
||||
$(libc_static_common_src_files) \
|
||||
bionic/malloc_debug_common.cpp \
|
||||
bionic/debug_mapinfo.cpp \
|
||||
bionic/debug_stacktrace.cpp \
|
||||
bionic/libc_init_dynamic.cpp \
|
||||
bionic/NetdClient.cpp \
|
||||
|
||||
@ -1047,7 +1045,10 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
# Make sure that unwind.h comes from libunwind.
|
||||
LOCAL_C_INCLUDES := \
|
||||
external/libunwind/include \
|
||||
$(libc_common_c_includes) \
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
bionic/debug_mapinfo.cpp \
|
||||
@ -1062,6 +1063,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libc libdl
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libunwindbacktrace
|
||||
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
|
||||
|
||||
# Don't install on release build
|
||||
|
@ -26,39 +26,48 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "debug_mapinfo.h"
|
||||
#include "malloc_debug_disable.h"
|
||||
|
||||
// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so
|
||||
// 012345678901234567890123456789012345678901234567890123456789
|
||||
// 0 1 2 3 4 5
|
||||
|
||||
// Format of /proc/<PID>/maps:
|
||||
// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so
|
||||
static mapinfo_t* parse_maps_line(char* line) {
|
||||
int len = strlen(line);
|
||||
uintptr_t start;
|
||||
uintptr_t end;
|
||||
int name_pos;
|
||||
if (sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d%n", &start,
|
||||
&end, &name_pos) < 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < 1) return 0;
|
||||
line[--len] = 0;
|
||||
|
||||
if (len < 50) return 0;
|
||||
if (line[20] != 'x') return 0;
|
||||
|
||||
mapinfo_t* mi = static_cast<mapinfo_t*>(
|
||||
mmap(NULL, sizeof(mapinfo_t) + (len - 47), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0));
|
||||
if (mi == MAP_FAILED) return 0;
|
||||
|
||||
mi->start = strtoul(line, 0, 16);
|
||||
mi->end = strtoul(line + 9, 0, 16);
|
||||
mi->next = 0;
|
||||
strcpy(mi->name, line + 49);
|
||||
while (isspace(line[name_pos])) {
|
||||
name_pos += 1;
|
||||
}
|
||||
const char* name = line + name_pos;
|
||||
size_t name_len = strlen(name);
|
||||
if (name_len && name[name_len - 1] == '\n') {
|
||||
name_len -= 1;
|
||||
}
|
||||
|
||||
mapinfo_t* mi = reinterpret_cast<mapinfo_t*>(calloc(1, sizeof(mapinfo_t) + name_len + 1));
|
||||
if (mi) {
|
||||
mi->start = start;
|
||||
mi->end = end;
|
||||
memcpy(mi->name, name, name_len);
|
||||
mi->name[name_len] = '\0';
|
||||
}
|
||||
return mi;
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ mapinfo_t* mapinfo_create(pid_t pid) {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
struct mapinfo_t* milist = NULL;
|
||||
char data[1024]; // Used to read lines as well as to construct the filename.
|
||||
snprintf(data, sizeof(data), "/proc/%d/maps", pid);
|
||||
@ -77,10 +86,12 @@ __LIBC_HIDDEN__ mapinfo_t* mapinfo_create(pid_t pid) {
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ void mapinfo_destroy(mapinfo_t* mi) {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
while (mi != NULL) {
|
||||
mapinfo_t* del = mi;
|
||||
mi = mi->next;
|
||||
munmap(del, sizeof(mapinfo_t) + strlen(del->name) + 2);
|
||||
free(del);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
|
||||
struct mapinfo_t {
|
||||
struct mapinfo_t* next;
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
uintptr_t start;
|
||||
uintptr_t end;
|
||||
char name[];
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "debug_mapinfo.h"
|
||||
#include "malloc_debug_disable.h"
|
||||
#include "private/libc_logging.h"
|
||||
|
||||
#if defined(__LP64__)
|
||||
@ -56,6 +57,8 @@ typedef char* (*DemanglerFn)(const char*, char*, size_t*, int*);
|
||||
static DemanglerFn g_demangler_fn = NULL;
|
||||
|
||||
__LIBC_HIDDEN__ void backtrace_startup() {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
g_map_info = mapinfo_create(getpid());
|
||||
g_demangler = dlopen("libgccdemangle.so", RTLD_NOW);
|
||||
if (g_demangler != NULL) {
|
||||
@ -65,6 +68,8 @@ __LIBC_HIDDEN__ void backtrace_startup() {
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ void backtrace_shutdown() {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
mapinfo_destroy(g_map_info);
|
||||
dlclose(g_demangler);
|
||||
}
|
||||
@ -98,7 +103,7 @@ static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg)
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#ifdef __arm__
|
||||
#if defined(__arm__)
|
||||
/*
|
||||
* The instruction pointer is pointing at the instruction after the bl(x), and
|
||||
* the _Unwind_Backtrace routine already masks the Thumb mode indicator (LSB
|
||||
@ -121,12 +126,16 @@ static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg)
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ int get_backtrace(uintptr_t* frames, size_t max_depth) {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
stack_crawl_state_t state(frames, max_depth);
|
||||
_Unwind_Backtrace(trace_function, &state);
|
||||
return state.frame_count;
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
uintptr_t self_bt[16];
|
||||
if (frames == NULL) {
|
||||
frame_count = get_backtrace(self_bt, 16);
|
||||
@ -146,7 +155,7 @@ __LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) {
|
||||
symbol = info.dli_sname;
|
||||
}
|
||||
|
||||
uintptr_t rel_pc;
|
||||
uintptr_t rel_pc = offset;
|
||||
const mapinfo_t* mi = (g_map_info != NULL) ? mapinfo_find(g_map_info, frames[i], &rel_pc) : NULL;
|
||||
const char* soname = (mi != NULL) ? mi->name : info.dli_fname;
|
||||
if (soname == NULL) {
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "debug_mapinfo.h"
|
||||
#include "debug_stacktrace.h"
|
||||
#include "malloc_debug_common.h"
|
||||
#include "malloc_debug_disable.h"
|
||||
#include "private/bionic_macros.h"
|
||||
#include "private/libc_logging.h"
|
||||
#include "private/ScopedPthreadMutexLocker.h"
|
||||
@ -331,6 +332,9 @@ static inline void add_to_backlog(hdr_t* hdr) {
|
||||
|
||||
extern "C" void* chk_malloc(size_t bytes) {
|
||||
// log_message("%s: %s\n", __FILE__, __FUNCTION__);
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->malloc(bytes);
|
||||
}
|
||||
|
||||
size_t size = sizeof(hdr_t) + bytes + sizeof(ftr_t);
|
||||
if (size < bytes) { // Overflow
|
||||
@ -348,6 +352,10 @@ extern "C" void* chk_malloc(size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" void* chk_memalign(size_t alignment, size_t bytes) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->memalign(alignment, bytes);
|
||||
}
|
||||
|
||||
if (alignment <= MALLOC_ALIGNMENT) {
|
||||
return chk_malloc(bytes);
|
||||
}
|
||||
@ -386,6 +394,9 @@ extern "C" void* chk_memalign(size_t alignment, size_t bytes) {
|
||||
|
||||
extern "C" void chk_free(void* ptr) {
|
||||
// log_message("%s: %s\n", __FILE__, __FUNCTION__);
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->free(ptr);
|
||||
}
|
||||
|
||||
if (!ptr) /* ignore free(NULL) */
|
||||
return;
|
||||
@ -421,6 +432,9 @@ extern "C" void chk_free(void* ptr) {
|
||||
|
||||
extern "C" void* chk_realloc(void* ptr, size_t bytes) {
|
||||
// log_message("%s: %s\n", __FILE__, __FUNCTION__);
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->realloc(ptr, bytes);
|
||||
}
|
||||
|
||||
if (!ptr) {
|
||||
return chk_malloc(bytes);
|
||||
@ -496,6 +510,10 @@ extern "C" void* chk_realloc(void* ptr, size_t bytes) {
|
||||
|
||||
extern "C" void* chk_calloc(size_t nmemb, size_t bytes) {
|
||||
// log_message("%s: %s\n", __FILE__, __FUNCTION__);
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->calloc(nmemb, bytes);
|
||||
}
|
||||
|
||||
size_t total_bytes = nmemb * bytes;
|
||||
size_t size = sizeof(hdr_t) + total_bytes + sizeof(ftr_t);
|
||||
if (size < total_bytes || (nmemb && SIZE_MAX / nmemb < bytes)) { // Overflow
|
||||
@ -513,6 +531,10 @@ extern "C" void* chk_calloc(size_t nmemb, size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" size_t chk_malloc_usable_size(const void* ptr) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->malloc_usable_size(ptr);
|
||||
}
|
||||
|
||||
// malloc_usable_size returns 0 for NULL and unknown blocks.
|
||||
if (ptr == NULL)
|
||||
return 0;
|
||||
@ -529,6 +551,10 @@ extern "C" struct mallinfo chk_mallinfo() {
|
||||
}
|
||||
|
||||
extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->posix_memalign(memptr, alignment, size);
|
||||
}
|
||||
|
||||
if (!powerof2(alignment)) {
|
||||
return EINVAL;
|
||||
}
|
||||
@ -538,7 +564,12 @@ extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size)
|
||||
return (*memptr != NULL) ? 0 : ENOMEM;
|
||||
}
|
||||
|
||||
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
|
||||
extern "C" void* chk_pvalloc(size_t bytes) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->pvalloc(bytes);
|
||||
}
|
||||
|
||||
size_t pagesize = getpagesize();
|
||||
size_t size = BIONIC_ALIGN(bytes, pagesize);
|
||||
if (size < bytes) { // Overflow
|
||||
@ -548,10 +579,16 @@ extern "C" void* chk_pvalloc(size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" void* chk_valloc(size_t size) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->valloc(size);
|
||||
}
|
||||
return chk_memalign(getpagesize(), size);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ReportMemoryLeaks() {
|
||||
ScopedDisableDebugCalls disable;
|
||||
|
||||
// Use /proc/self/exe link to obtain the program name for logging
|
||||
// purposes. If it's not available, we set it to "<unknown>".
|
||||
char exe[PATH_MAX];
|
||||
@ -585,10 +622,14 @@ static void ReportMemoryLeaks() {
|
||||
}
|
||||
}
|
||||
|
||||
pthread_key_t g_debug_calls_disabled;
|
||||
|
||||
extern "C" bool malloc_debug_initialize(HashTable* hash_table, const MallocDebug* malloc_dispatch) {
|
||||
g_hash_table = hash_table;
|
||||
g_malloc_dispatch = malloc_dispatch;
|
||||
|
||||
pthread_key_create(&g_debug_calls_disabled, NULL);
|
||||
|
||||
char debug_backlog[PROP_VALUE_MAX];
|
||||
if (__system_property_get("libc.debug.malloc.backlog", debug_backlog)) {
|
||||
g_malloc_debug_backlog = atoi(debug_backlog);
|
||||
@ -605,4 +646,6 @@ extern "C" void malloc_debug_finalize(int malloc_debug_level) {
|
||||
ReportMemoryLeaks();
|
||||
}
|
||||
backtrace_shutdown();
|
||||
|
||||
pthread_setspecific(g_debug_calls_disabled, NULL);
|
||||
}
|
||||
|
64
libc/bionic/malloc_debug_disable.h
Normal file
64
libc/bionic/malloc_debug_disable.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MALLOC_DEBUG_DISABLE_H
|
||||
#define MALLOC_DEBUG_DISABLE_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "private/bionic_macros.h"
|
||||
|
||||
// =============================================================================
|
||||
// Used to disable the debug allocation calls.
|
||||
// =============================================================================
|
||||
extern pthread_key_t g_debug_calls_disabled;
|
||||
|
||||
static inline bool DebugCallsDisabled() {
|
||||
return pthread_getspecific(g_debug_calls_disabled) != NULL;
|
||||
}
|
||||
|
||||
class ScopedDisableDebugCalls {
|
||||
public:
|
||||
ScopedDisableDebugCalls() : disabled_(DebugCallsDisabled()) {
|
||||
if (!disabled_) {
|
||||
pthread_setspecific(g_debug_calls_disabled, reinterpret_cast<const void*>(1));
|
||||
}
|
||||
}
|
||||
~ScopedDisableDebugCalls() {
|
||||
if (!disabled_) {
|
||||
pthread_setspecific(g_debug_calls_disabled, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool disabled_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedDisableDebugCalls);
|
||||
};
|
||||
|
||||
#endif // MALLOC_DEBUG_DISABLE_H
|
@ -48,6 +48,7 @@
|
||||
|
||||
#include "debug_stacktrace.h"
|
||||
#include "malloc_debug_common.h"
|
||||
#include "malloc_debug_disable.h"
|
||||
|
||||
#include "private/bionic_macros.h"
|
||||
#include "private/libc_logging.h"
|
||||
@ -267,6 +268,7 @@ extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size)
|
||||
return (*memptr != NULL) ? 0 : ENOMEM;
|
||||
}
|
||||
|
||||
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
|
||||
extern "C" void* fill_pvalloc(size_t bytes) {
|
||||
size_t pagesize = getpagesize();
|
||||
size_t size = BIONIC_ALIGN(bytes, pagesize);
|
||||
@ -279,6 +281,7 @@ extern "C" void* fill_pvalloc(size_t bytes) {
|
||||
extern "C" void* fill_valloc(size_t size) {
|
||||
return fill_memalign(getpagesize(), size);
|
||||
}
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
// malloc leak functions
|
||||
@ -287,6 +290,10 @@ extern "C" void* fill_valloc(size_t size) {
|
||||
static uint32_t MEMALIGN_GUARD = 0xA1A41520;
|
||||
|
||||
extern "C" void* leak_malloc(size_t bytes) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->malloc(bytes);
|
||||
}
|
||||
|
||||
// allocate enough space infront of the allocation to store the pointer for
|
||||
// the alloc structure. This will making free'ing the structer really fast!
|
||||
|
||||
@ -319,6 +326,10 @@ extern "C" void* leak_malloc(size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" void leak_free(void* mem) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->free(mem);
|
||||
}
|
||||
|
||||
if (mem == NULL) {
|
||||
return;
|
||||
}
|
||||
@ -355,6 +366,10 @@ extern "C" void leak_free(void* mem) {
|
||||
}
|
||||
|
||||
extern "C" void* leak_calloc(size_t n_elements, size_t elem_size) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->calloc(n_elements, 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) {
|
||||
@ -370,6 +385,10 @@ extern "C" void* leak_calloc(size_t n_elements, size_t elem_size) {
|
||||
}
|
||||
|
||||
extern "C" void* leak_realloc(void* oldMem, size_t bytes) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->realloc(oldMem, bytes);
|
||||
}
|
||||
|
||||
if (oldMem == NULL) {
|
||||
return leak_malloc(bytes);
|
||||
}
|
||||
@ -398,6 +417,10 @@ extern "C" void* leak_realloc(void* oldMem, size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" void* leak_memalign(size_t alignment, size_t bytes) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->memalign(alignment, bytes);
|
||||
}
|
||||
|
||||
// we can just use malloc
|
||||
if (alignment <= MALLOC_ALIGNMENT) {
|
||||
return leak_malloc(bytes);
|
||||
@ -439,6 +462,10 @@ extern "C" void* leak_memalign(size_t alignment, size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" size_t leak_malloc_usable_size(const void* mem) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->malloc_usable_size(mem);
|
||||
}
|
||||
|
||||
if (mem != NULL) {
|
||||
// Check the guard to make sure it is valid.
|
||||
const AllocationEntry* header = const_to_header((void*)mem);
|
||||
@ -467,6 +494,10 @@ extern "C" struct mallinfo leak_mallinfo() {
|
||||
}
|
||||
|
||||
extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->posix_memalign(memptr, alignment, size);
|
||||
}
|
||||
|
||||
if (!powerof2(alignment)) {
|
||||
return EINVAL;
|
||||
}
|
||||
@ -476,7 +507,12 @@ extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size)
|
||||
return (*memptr != NULL) ? 0 : ENOMEM;
|
||||
}
|
||||
|
||||
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
|
||||
extern "C" void* leak_pvalloc(size_t bytes) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->pvalloc(bytes);
|
||||
}
|
||||
|
||||
size_t pagesize = getpagesize();
|
||||
size_t size = BIONIC_ALIGN(bytes, pagesize);
|
||||
if (size < bytes) { // Overflow
|
||||
@ -486,5 +522,10 @@ extern "C" void* leak_pvalloc(size_t bytes) {
|
||||
}
|
||||
|
||||
extern "C" void* leak_valloc(size_t size) {
|
||||
if (DebugCallsDisabled()) {
|
||||
return g_malloc_dispatch->valloc(size);
|
||||
}
|
||||
|
||||
return leak_memalign(getpagesize(), size);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user