Merge "Update a comment for init_linker_info_for_gdb"
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index 92b866d..0447566 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -82,3 +82,21 @@
}
return true;
}
+
+void DebugData::PrepareFork() {
+ if (track != nullptr) {
+ track->PrepareFork();
+ }
+}
+
+void DebugData::PostForkParent() {
+ if (track != nullptr) {
+ track->PostForkParent();
+ }
+}
+
+void DebugData::PostForkChild() {
+ if (track != nullptr) {
+ track->PostForkChild();
+ }
+}
diff --git a/libc/malloc_debug/DebugData.h b/libc/malloc_debug/DebugData.h
index 40978db..4600b33 100644
--- a/libc/malloc_debug/DebugData.h
+++ b/libc/malloc_debug/DebugData.h
@@ -82,6 +82,10 @@
bool need_header() { return need_header_; }
size_t extra_bytes() { return extra_bytes_; }
+ void PrepareFork();
+ void PostForkParent();
+ void PostForkChild();
+
std::unique_ptr<BacktraceData> backtrace;
std::unique_ptr<TrackData> track;
std::unique_ptr<FrontGuardData> front_guard;
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
index 45e6892..dcf0ede 100644
--- a/libc/malloc_debug/TrackData.h
+++ b/libc/malloc_debug/TrackData.h
@@ -58,6 +58,10 @@
void DisplayLeaks(DebugData& debug);
+ void PrepareFork() { pthread_mutex_lock(&mutex_); }
+ void PostForkParent() { pthread_mutex_unlock(&mutex_); }
+ void PostForkChild() { pthread_mutex_init(&mutex_, NULL); }
+
private:
pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
std::unordered_set<Header*> headers_;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 0c0907d..dcc6048 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -85,6 +85,28 @@
__END_DECLS
// ------------------------------------------------------------------------
+static void InitAtfork() {
+ static pthread_once_t atfork_init = PTHREAD_ONCE_INIT;
+ pthread_once(&atfork_init, [](){
+ pthread_atfork(
+ [](){
+ if (g_debug != nullptr) {
+ g_debug->PrepareFork();
+ }
+ },
+ [](){
+ if (g_debug != nullptr) {
+ g_debug->PostForkParent();
+ }
+ },
+ [](){
+ if (g_debug != nullptr) {
+ g_debug->PostForkChild();
+ }
+ }
+ );
+ });
+}
static void LogTagError(const Header* header, const void* pointer, const char* name) {
ScopedDisableDebugCalls disable;
@@ -156,6 +178,9 @@
if (malloc_zygote_child == nullptr) {
return false;
}
+
+ InitAtfork();
+
g_malloc_zygote_child = malloc_zygote_child;
g_dispatch = malloc_dispatch;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b013dca..fbb9f11 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -216,14 +216,7 @@
static link_map* r_debug_tail = 0;
-static void insert_soinfo_into_debug_map(soinfo* info) {
- // Copy the necessary fields into the debug structure.
- link_map* map = &(info->link_map_head);
- map->l_addr = info->load_bias;
- // link_map l_name field is not const.
- map->l_name = const_cast<char*>(info->get_realpath());
- map->l_ld = info->dynamic;
-
+static void insert_link_map_into_debug_map(link_map* map) {
// Stick the new library at the end of the list.
// gdb tends to care more about libc than it does
// about leaf libraries, and ordering it this way
@@ -240,6 +233,17 @@
r_debug_tail = map;
}
+static void insert_soinfo_into_debug_map(soinfo* info) {
+ // Copy the necessary fields into the debug structure.
+ link_map* map = &(info->link_map_head);
+ map->l_addr = info->load_bias;
+ // link_map l_name field is not const.
+ map->l_name = const_cast<char*>(info->get_realpath());
+ map->l_ld = info->dynamic;
+
+ insert_link_map_into_debug_map(map);
+}
+
static void remove_soinfo_from_debug_map(soinfo* info) {
link_map* map = &(info->link_map_head);
@@ -3885,21 +3889,6 @@
#endif
}
-/*
- * This is linker soinfo for GDB. See details below.
- */
-#if defined(__LP64__)
-#define LINKER_PATH "/system/bin/linker64"
-#else
-#define LINKER_PATH "/system/bin/linker"
-#endif
-
-// This is done to avoid calling c-tor prematurely
-// because soinfo c-tor needs memory allocator
-// which might be initialized after global variables.
-static uint8_t linker_soinfo_for_gdb_buf[sizeof(soinfo)] __attribute__((aligned(8)));
-static soinfo* linker_soinfo_for_gdb = nullptr;
-
/* gdb expects the linker to be in the debug shared object list.
* Without this, gdb has trouble locating the linker's ".text"
* and ".plt" sections. Gdb could also potentially use this to
@@ -3907,10 +3896,15 @@
* Note that the linker shouldn't be on the soinfo list.
*/
static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
- linker_soinfo_for_gdb = new (linker_soinfo_for_gdb_buf) soinfo(nullptr, LINKER_PATH,
- nullptr, 0, 0);
+ static link_map linker_link_map_for_gdb;
+#if defined(__LP64__)
+ static char kLinkerPath[] = "/system/bin/linker64";
+#else
+ static char kLinkerPath[] = "/system/bin/linker";
+#endif
- linker_soinfo_for_gdb->load_bias = linker_base;
+ linker_link_map_for_gdb.l_addr = linker_base;
+ linker_link_map_for_gdb.l_name = kLinkerPath;
/*
* Set the dynamic field in the link map otherwise gdb will complain with
@@ -3921,8 +3915,9 @@
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_base);
ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_base + elf_hdr->e_phoff);
phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base,
- &linker_soinfo_for_gdb->dynamic, nullptr);
- insert_soinfo_into_debug_map(linker_soinfo_for_gdb);
+ &linker_link_map_for_gdb.l_ld, nullptr);
+
+ insert_link_map_into_debug_map(&linker_link_map_for_gdb);
}
static void init_default_namespace() {
@@ -4016,7 +4011,6 @@
// Extract information passed from the kernel.
si->phdr = reinterpret_cast<ElfW(Phdr)*>(args.getauxval(AT_PHDR));
si->phnum = args.getauxval(AT_PHNUM);
- si->entry = args.getauxval(AT_ENTRY);
/* Compute the value of si->base. We can't rely on the fact that
* the first entry is the PHDR because this will not be true
@@ -4145,8 +4139,9 @@
fflush(stdout);
#endif
- TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
- return si->entry;
+ ElfW(Addr) entry = args.getauxval(AT_ENTRY);
+ TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(entry));
+ return entry;
}
/* Compute the load-bias of an existing executable. This shall only
diff --git a/linker/linker.h b/linker/linker.h
index 389c5b3..c669c46 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -173,7 +173,9 @@
public:
const ElfW(Phdr)* phdr;
size_t phnum;
- ElfW(Addr) entry;
+#if defined(__work_around_b_24465209__)
+ ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility.
+#endif
ElfW(Addr) base;
size_t size;