Merge "Remove unused .mk file."
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 1c3f53f..ce3e761 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -303,23 +303,25 @@
return true;
}
-static void InstallHooks(libc_globals* globals, const char* options, const char* prefix,
+static bool InstallHooks(libc_globals* globals, const char* options, const char* prefix,
const char* shared_lib) {
void* impl_handle = LoadSharedLibrary(shared_lib, prefix, &globals->malloc_dispatch_table);
if (impl_handle == nullptr) {
- return;
+ return false;
}
init_func_t init_func = reinterpret_cast<init_func_t>(gFunctions[FUNC_INITIALIZE]);
if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild, options)) {
error_log("%s: failed to enable malloc %s", getprogname(), prefix);
ClearGlobalFunctions();
- return;
+ return false;
}
if (!FinishInstallHooks(globals, options, prefix)) {
dlclose(impl_handle);
+ return false;
}
+ return true;
}
// Initializes memory allocation framework once per process.
@@ -329,16 +331,25 @@
// Prefer malloc debug since it existed first and is a more complete
// malloc interceptor than the hooks.
+ bool hook_installed = false;
if (CheckLoadMallocDebug(&options)) {
- InstallHooks(globals, options, kDebugPrefix, kDebugSharedLib);
+ hook_installed = InstallHooks(globals, options, kDebugPrefix, kDebugSharedLib);
} else if (CheckLoadMallocHooks(&options)) {
- InstallHooks(globals, options, kHooksPrefix, kHooksSharedLib);
- } else if (HeapprofdShouldLoad()) {
- HeapprofdInstallHooksAtInit(globals);
+ hook_installed = InstallHooks(globals, options, kHooksPrefix, kHooksSharedLib);
}
- // Install this last to avoid as many race conditions as possible.
- HeapprofdInstallSignalHandler();
+ if (!hook_installed) {
+ if (HeapprofdShouldLoad()) {
+ HeapprofdInstallHooksAtInit(globals);
+ }
+
+ // Install this last to avoid as many race conditions as possible.
+ HeapprofdInstallSignalHandler();
+ } else {
+ // Install a signal handler that prints an error since we don't support
+ // heapprofd and any other hook to be installed at the same time.
+ HeapprofdInstallErrorSignalHandler();
+ }
}
// Initializes memory allocation framework.
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index fb7266a..c492bac 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -211,6 +211,16 @@
sigaction(kHeapprofdSignal, &action, nullptr);
}
+static void DisplayError(int) {
+ error_log("Cannot install heapprofd while malloc debug/malloc hooks are enabled.");
+}
+
+void HeapprofdInstallErrorSignalHandler() {
+ struct sigaction action = {};
+ action.sa_handler = DisplayError;
+ sigaction(kHeapprofdSignal, &action, nullptr);
+}
+
static void CommonInstallHooks(libc_globals* globals) {
void* impl_handle = atomic_load(&gHeapprofdHandle);
bool reusing_handle = impl_handle != nullptr;
diff --git a/libc/bionic/malloc_heapprofd.h b/libc/bionic/malloc_heapprofd.h
index 91188b9..5a766fc 100644
--- a/libc/bionic/malloc_heapprofd.h
+++ b/libc/bionic/malloc_heapprofd.h
@@ -38,4 +38,6 @@
void HeapprofdInstallSignalHandler();
+void HeapprofdInstallErrorSignalHandler();
+
bool HeapprofdMallopt(int optcode, void* arg, size_t arg_size);
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 638061b..6e9d24f 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -266,12 +266,12 @@
error_log(" hash_index %zu does not have matching frame data.", hash_index);
}
-void PointerData::LogFreeError(const FreePointerInfoType& info, size_t usable_size) {
+void PointerData::LogFreeError(const FreePointerInfoType& info, size_t max_cmp_bytes) {
error_log(LOG_DIVIDER);
uint8_t* memory = reinterpret_cast<uint8_t*>(info.pointer);
error_log("+++ ALLOCATION %p USED AFTER FREE", memory);
uint8_t fill_free_value = g_debug->config().fill_free_value();
- for (size_t i = 0; i < usable_size; i++) {
+ for (size_t i = 0; i < max_cmp_bytes; i++) {
if (memory[i] != fill_free_value) {
error_log(" allocation[%zu] = 0x%02x (expected 0x%02x)", i, memory[i], fill_free_value);
}
@@ -314,11 +314,12 @@
size_t bytes = (usable_size < g_debug->config().fill_on_free_bytes())
? usable_size
: g_debug->config().fill_on_free_bytes();
+ size_t max_cmp_bytes = bytes;
const uint8_t* memory = reinterpret_cast<const uint8_t*>(info.pointer);
while (bytes > 0) {
size_t bytes_to_cmp = (bytes < g_cmp_mem.size()) ? bytes : g_cmp_mem.size();
if (memcmp(memory, g_cmp_mem.data(), bytes_to_cmp) != 0) {
- LogFreeError(info, usable_size);
+ LogFreeError(info, max_cmp_bytes);
}
bytes -= bytes_to_cmp;
memory = &memory[bytes_to_cmp];
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 44f9795..6da95ca 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -990,6 +990,35 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, free_track_pointer_modified_after_free) {
+ Init("free_track=4 fill_on_free=2 free_track_backtrace_num_frames=0");
+
+ void* pointers[5];
+ for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
+ pointers[i] = debug_malloc(100);
+ ASSERT_TRUE(pointers[i] != nullptr);
+ memset(pointers[i], 0, 100);
+ }
+
+ debug_free(pointers[0]);
+
+ // overwrite the whole pointer, only expect errors on the fill bytes we check.
+ memset(pointers[0], 0x20, 100);
+
+ for (size_t i = 1; i < sizeof(pointers) / sizeof(void*); i++) {
+ debug_free(pointers[i]);
+ }
+
+ std::string expected_log(DIVIDER);
+ expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n",
+ pointers[0]);
+ expected_log += "6 malloc_debug allocation[0] = 0x20 (expected 0xef)\n";
+ expected_log += "6 malloc_debug allocation[1] = 0x20 (expected 0xef)\n";
+ expected_log += DIVIDER;
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
Init("fill");
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
index c39fac5..6fcc09e 100644
--- a/libc/symbol_ordering
+++ b/libc/symbol_ordering
@@ -3,8 +3,6 @@
# symbols by size, we usually have less dirty pages at runtime, because small
# symbols are grouped together.
-je_background_thread_enabled_state
-je_can_enable_background_thread
_ZZ17__find_icu_symbolPKcE9found_icu
_ZL24gHeapprofdInitInProgress
_ZL27gHeapprofdInitHookInstalled
@@ -19,7 +17,6 @@
had_conf_error
malloc_slow_flags
je_opt_background_thread
-background_thread_enabled_at_fork
ctl_initialized
je_log_init_done
mmap_flags
@@ -70,8 +67,6 @@
seed48.sseed
ether_aton.addr
je_background_thread_info
-je_max_background_threads
-je_n_background_threads
je_malloc_message
je_tcache_bin_info
je_tcache_maxclass
@@ -92,7 +87,6 @@
je_opt_muzzy_decay_ms
dirty_decay_ms_default.0
muzzy_decay_ms_default.0
-pthread_create_fptr
b0
ctl_arenas
ctl_stats
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 43ddbfe..642cc7a 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -92,6 +92,8 @@
nocrt: true,
system_shared_libs: [],
+
+ // Opt out of native_coverage when opting out of system_shared_libs
native_coverage: false,
// This is placeholder library the actual implementation is (currently)
diff --git a/linker/Android.bp b/linker/Android.bp
index fed921d..06a942d 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -296,6 +296,10 @@
},
},
system_shared_libs: [],
+
+ // Opt out of native_coverage when opting out of system_shared_libs
+ native_coverage: false,
+
target: {
android: {
static_libs: ["libdebuggerd_handler_fallback"],
@@ -364,6 +368,9 @@
nocrt: true,
system_shared_libs: [],
+ // Opt out of native_coverage when opting out of system_shared_libs
+ native_coverage: false,
+
sanitize: {
never: true,
},
diff --git a/tests/malloc_iterate_test.cpp b/tests/malloc_iterate_test.cpp
index 5e60a6d..76583eb 100644
--- a/tests/malloc_iterate_test.cpp
+++ b/tests/malloc_iterate_test.cpp
@@ -92,14 +92,15 @@
test_data->total_allocated_bytes = 0;
// Find all of the maps that are [anon:libc_malloc].
- ASSERT_TRUE(android::procinfo::ReadMapFile("/proc/self/maps",
- [&](uint64_t start, uint64_t end, uint16_t, uint64_t, const char* name) {
- if (std::string(name) == "[anon:libc_malloc]") {
- malloc_disable();
- malloc_iterate(start, end - start, SavePointers, test_data);
- malloc_enable();
- }
- }));
+ ASSERT_TRUE(android::procinfo::ReadMapFile(
+ "/proc/self/maps",
+ [&](uint64_t start, uint64_t end, uint16_t, uint64_t, ino_t, const char* name) {
+ if (std::string(name) == "[anon:libc_malloc]") {
+ malloc_disable();
+ malloc_iterate(start, end - start, SavePointers, test_data);
+ malloc_enable();
+ }
+ }));
for (size_t i = 0; i < test_data->allocs.size(); i++) {
EXPECT_EQ(1UL, test_data->allocs[i].count) << "Failed on size " << test_data->allocs[i].size;
@@ -180,14 +181,15 @@
TestDataType test_data = {};
// Find all of the maps that are not [anon:libc_malloc].
- ASSERT_TRUE(android::procinfo::ReadMapFile("/proc/self/maps",
- [&](uint64_t start, uint64_t end, uint16_t, uint64_t, const char* name) {
- if (std::string(name) != "[anon:libc_malloc]") {
- malloc_disable();
- malloc_iterate(start, end - start, SavePointers, &test_data);
- malloc_enable();
- }
- }));
+ ASSERT_TRUE(android::procinfo::ReadMapFile(
+ "/proc/self/maps",
+ [&](uint64_t start, uint64_t end, uint16_t, uint64_t, ino_t, const char* name) {
+ if (std::string(name) != "[anon:libc_malloc]") {
+ malloc_disable();
+ malloc_iterate(start, end - start, SavePointers, &test_data);
+ malloc_enable();
+ }
+ }));
ASSERT_EQ(0UL, test_data.total_allocated_bytes);
#else