platform_bionic/libc/bionic/malloc_common.h
Ryan Savitski 175c8867b0 allow for heapprofd's signal to be multiplexed
This patch refactors heapprofd_malloc to make it easier to reuse the
reserved signal for multiple purposes. We define a new generic signal
handler for profilers, which dispatches to more specific logic based on
the signal's payload (si_value).

The profiler signal handler is installed during libc preinit, after
malloc initialization (so races against synchronous heapprofd
initialization need not be considered). In terms of code organization, I
copied the existing approach with a loosely referenced function in
bionic_globals.h. Do tell if you'd rather a different approach here.

The profileability of a process is quite tied to the malloc
files/interfaces in bionic - in particular, it's set through
android_mallopt. I do not change that, but instead introduce a new
android_mallopt option to be able to query profileability of the
process (which is now used by the new profiler signal handler). As part
of that, gZygoteChildProfileable is moved from heapprofd_malloc to
common (alongside gZygoteChild).

I've removed the masking and reraising of the heapprofd signal when
racing against malloc_limit init. We're ok with taking a simpler
approach and dropping the heapprofd signal in such an unlikely race.

Note: this requires a corresponding change in heapprofd to use sigqueue()
instead of kill(), as the latter leaves the si_value uninitialized(?) on
the receiving side.

Bug: 144281346
Change-Id: I93bb2e82cff5870e5ca499cf86439860aca9dfa5
2020-01-15 22:55:03 +00:00

94 lines
3.2 KiB
C

/*
* Copyright (C) 2019 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.
*/
#pragma once
#include <stdatomic.h>
#include <stdio.h>
#include <async_safe/log.h>
#include <private/bionic_globals.h>
#include <private/bionic_malloc_dispatch.h>
#if __has_feature(hwaddress_sanitizer)
#include <sanitizer/hwasan_interface.h>
__BEGIN_DECLS
// FIXME: implement these in HWASan allocator.
int __sanitizer_malloc_iterate(uintptr_t base, size_t size,
void (*callback)(uintptr_t base, size_t size, void* arg),
void* arg);
void __sanitizer_malloc_disable();
void __sanitizer_malloc_enable();
int __sanitizer_malloc_info(int options, FILE* fp);
__END_DECLS
#define Malloc(function) __sanitizer_ ## function
#else // __has_feature(hwaddress_sanitizer)
#if defined(USE_SCUDO)
#include "scudo.h"
#define Malloc(function) scudo_ ## function
#elif defined(USE_SCUDO_SVELTE)
#include "scudo.h"
#define Malloc(function) scudo_svelte_ ## function
#else
#include "jemalloc.h"
#define Malloc(function) je_ ## function
#endif
#endif
static inline const MallocDispatch* GetDispatchTable() {
return atomic_load_explicit(&__libc_globals->current_dispatch_table, memory_order_acquire);
}
static inline const MallocDispatch* GetDefaultDispatchTable() {
return atomic_load_explicit(&__libc_globals->default_dispatch_table, memory_order_acquire);
}
// =============================================================================
// Log functions
// =============================================================================
#define error_log(format, ...) \
async_safe_format_log(ANDROID_LOG_ERROR, "libc", (format), ##__VA_ARGS__ )
#define info_log(format, ...) \
async_safe_format_log(ANDROID_LOG_INFO, "libc", (format), ##__VA_ARGS__ )
#define warning_log(format, ...) \
async_safe_format_log(ANDROID_LOG_WARN, "libc", (format), ##__VA_ARGS__ )
// =============================================================================