From 9ccccc1a952c7abc99f5d912878b751d114c99bd Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Thu, 9 Feb 2017 10:54:44 -0800 Subject: linker: add android_use_fallback_allocator. Add a function to enable a fallback allocator to use for crash handling in a signal handler. Bug: http://b/34684590 Test: crasher PR_SET_NO_NEW_PRIVS Change-Id: Ifa5de636164f34b8cb2fdec4471c20f8516b6dbe --- linker/linker_memory.cpp | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'linker/linker_memory.cpp') diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp index 1892d02ca..918adb01a 100644 --- a/linker/linker_memory.cpp +++ b/linker/linker_memory.cpp @@ -17,22 +17,51 @@ #include "linker_allocator.h" #include +#include +#include + +#include "private/libc_logging.h" static LinkerMemoryAllocator g_linker_allocator; +static pid_t fallback_tid = 0; + +// Used by libdebuggerd_handler to switch allocators during a crash dump, in +// case the linker heap is corrupted. Do not use this function. +extern "C" void __linker_use_fallback_allocator() { + if (fallback_tid != 0) { + __libc_format_log(ANDROID_LOG_ERROR, "libc", + "attempted to set fallback allocator multiple times"); + return; + } + + fallback_tid = gettid(); +} + +static LinkerMemoryAllocator& get_fallback_allocator() { + static LinkerMemoryAllocator fallback_allocator; + return fallback_allocator; +} + +static LinkerMemoryAllocator& get_allocator() { + if (__predict_false(fallback_tid) && __predict_false(gettid() == fallback_tid)) { + return get_fallback_allocator(); + } + return g_linker_allocator; +} void* malloc(size_t byte_count) { - return g_linker_allocator.alloc(byte_count); + return get_allocator().alloc(byte_count); } void* calloc(size_t item_count, size_t item_size) { - return g_linker_allocator.alloc(item_count*item_size); + return get_allocator().alloc(item_count*item_size); } void* realloc(void* p, size_t byte_count) { - return g_linker_allocator.realloc(p, byte_count); + return get_allocator().realloc(p, byte_count); } void free(void* ptr) { - g_linker_allocator.free(ptr); + get_allocator().free(ptr); } -- cgit v1.2.3