From 1d01fe8980d332a85f730bf2d2fef9dcf707c041 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 23 Oct 2017 10:07:55 -0700 Subject: [PATCH] Fix LP32 large pid detection. Bug: http://b/68046352 Test: ran tests Change-Id: I89cb99173ca77e9457e677187430b61cedb55c04 --- docs/32-bit-abi.md | 11 +++++++++++ libc/bionic/libc_init_dynamic.cpp | 13 ++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md index eecbe6d33..5e3ae4590 100644 --- a/docs/32-bit-abi.md +++ b/docs/32-bit-abi.md @@ -57,3 +57,14 @@ On 32-bit Android, `time_t` is 32-bit. The header `` and type Android all use the 32-bit `time_t`. In the 64-bit ABI, `time_t` is 64-bit. + +`pthread_mutex_t` is too small for large pids +--------------------------------------------- + +This doesn't generally affect Android devices, because on devices +`/proc/sys/kernel/pid_max` is usually too small to hit the 16-bit limit, +but 32-bit bionic's `pthread_mutex` is a total of 32 bits, leaving just +16 bits for the owner thread id. This means bionic isn't able to support +mutexes for tids that don't fit in 16 bits. This typically manifests as +a hang in `pthread_mutex_lock` if the libc startup code doesn't detect +this condition and abort. diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp index 349d4884b..0b682808f 100644 --- a/libc/bionic/libc_init_dynamic.cpp +++ b/libc/bionic/libc_init_dynamic.cpp @@ -77,11 +77,14 @@ static void __libc_preinit_impl(KernelArgumentBlock& args) { netdClientInit(); } -// We flag the __libc_preinit function as a constructor to ensure -// that its address is listed in libc.so's .init_array section. -// This ensures that the function is called by the dynamic linker -// as soon as the shared library is loaded. -__attribute__((constructor)) static void __libc_preinit() { +// We flag the __libc_preinit function as a constructor to ensure that +// its address is listed in libc.so's .init_array section. +// This ensures that the function is called by the dynamic linker as +// soon as the shared library is loaded. +// We give this constructor priority 1 because we want libc's constructor +// to run before any others (such as the jemalloc constructor), and lower +// is better (http://b/68046352). +__attribute__((constructor(1))) static void __libc_preinit() { // Read the kernel argument block pointer from TLS. void** tls = __get_tls(); KernelArgumentBlock** args_slot = &reinterpret_cast(tls)[TLS_SLOT_BIONIC_PREINIT];