Refactor malloc common into distinct pieces.
The pieces:
- The malloc common shared by static and dynamic code (malloc_common.cpp).
- The code for shared libraries that includes any dlopen'ing
(malloc_common_dynamic.cpp).
- The implementation of perfetto's heapprofd (malloc_heapprofd.cpp).
This makes it easier to see what's going on in the many different areas.
It should also make it easier to add the allocation capping option.
Other related changes:
- Update the unit tests for android_mallopt. All of the current options
don't work on static binaries, so make sure that is reflected in the test.
- A few names changes to make sure that all code is consistent.
Test: Ran tests (malloc hooks/malloc debug/perfetto/bionic unit tests).
Change-Id: I0893bfbc0f83d82506fac5d1f37cf92fbdef6f59
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 1431cc1..658f8bd 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include <elf.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
@@ -24,6 +25,8 @@
#include <tinyxml2.h>
+#include <android-base/file.h>
+
#include "private/bionic_config.h"
#include "private/bionic_malloc.h"
#include "utils.h"
@@ -620,20 +623,48 @@
#endif
}
+bool IsDynamic() {
+#if defined(__LP64__)
+ Elf64_Ehdr ehdr;
+#else
+ Elf32_Ehdr ehdr;
+#endif
+ std::string path(android::base::GetExecutablePath());
+
+ int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
+ if (fd == -1) {
+ // Assume dynamic on error.
+ return true;
+ }
+ bool read_completed = android::base::ReadFully(fd, &ehdr, sizeof(ehdr));
+ close(fd);
+ // Assume dynamic in error cases.
+ return !read_completed || ehdr.e_type == ET_DYN;
+}
+
TEST(android_mallopt, init_zygote_child_profiling) {
#if defined(__BIONIC__)
// Successful call.
errno = 0;
- EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
- EXPECT_EQ(0, errno);
+ if (IsDynamic()) {
+ EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
+ EXPECT_EQ(0, errno);
+ } else {
+ // Not supported in static executables.
+ EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
+ EXPECT_EQ(ENOTSUP, errno);
+ }
// Unexpected arguments rejected.
errno = 0;
char unexpected = 0;
EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, &unexpected, 1));
- EXPECT_EQ(EINVAL, errno);
+ if (IsDynamic()) {
+ EXPECT_EQ(EINVAL, errno);
+ } else {
+ EXPECT_EQ(ENOTSUP, errno);
+ }
#else
GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
#endif
}
-