diff options
author | Josh Gao <jmgao@google.com> | 2017-02-09 10:54:44 -0800 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2017-02-15 17:00:16 -0800 |
commit | 9ccccc1a952c7abc99f5d912878b751d114c99bd (patch) | |
tree | 9d5016c3cd885a036cf34b868a035d920f8e549a /linker/linker_memory.cpp | |
parent | 273991ceadac558ba3bca5238d81833a7b34cb2d (diff) |
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
Diffstat (limited to 'linker/linker_memory.cpp')
-rw-r--r-- | linker/linker_memory.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
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 <stdlib.h> +#include <sys/cdefs.h> +#include <unistd.h> + +#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); } |