Merge "Fix deadlock/timeout in thread unwinding."
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 81afd14..3be6b1a 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -81,13 +81,23 @@
in the 64-bit ABI even though they're identical to the non-`64` names.
-## `time_t` is 32-bit
+## `time_t` is 32-bit on LP32 (y2038)
-On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type
-`time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit
-Android all use the 32-bit `time_t`.
+On 32-bit Android, `time_t` is 32-bit, which will overflow in 2038.
-In the 64-bit ABI, `time_t` is 64-bit.
+In the 64-bit ABI, `time_t` is 64-bit, which will not overflow until
+long after the death of the star around which we currently circle.
+
+The header `<time64.h>` and type `time64_t` exist as a workaround,
+but the kernel interfaces exposed on 32-bit Android all use the 32-bit
+`time_t` and `struct timespec`/`struct timeval`. Linux 5.x kernels
+do offer extra interfaces so that 32-bit processes can pass 64-bit
+times to/from the kernel, but we do not plan on adding support for
+these to the C library. Convenient use of the new calls would require
+an equivalent to `_FILE_OFFSET_BITS=64`, which we wouldn't be able
+to globally flip for reasons similar to `_FILE_OFFSET_BITS`, mentioned
+above. All apps are already required to offer 64-bit variants, and we
+expect 64-bit-only devices within the next few years.
## `pthread_mutex_t` is too small for large pids
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 583bf32..1cdb021 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -85,6 +85,28 @@
extern "C" int __rt_sigaction(int, const struct sigaction64*, struct sigaction64*, size_t);
+// sigaction and sigaction64 get interposed in ART: ensure that we don't end up calling
+// sigchain sigaction -> bionic sigaction -> sigchain sigaction64 -> bionic sigaction64
+// by extracting the implementation of sigaction64 to a static function.
+static int __sigaction64(int signal, const struct sigaction64* bionic_new,
+ struct sigaction64* bionic_old) {
+ struct sigaction64 kernel_new;
+ if (bionic_new) {
+ kernel_new = *bionic_new;
+#if defined(SA_RESTORER)
+ if (!(kernel_new.sa_flags & SA_RESTORER)) {
+ kernel_new.sa_flags |= SA_RESTORER;
+ kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
+ }
+#endif
+ // Don't filter signals here; if the caller asked for everything to be blocked, we should obey.
+ kernel_new.sa_mask = kernel_new.sa_mask;
+ }
+
+ return __rt_sigaction(signal, bionic_new ? &kernel_new : nullptr, bionic_old,
+ sizeof(kernel_new.sa_mask));
+}
+
int sigaction(int signal, const struct sigaction* bionic_new, struct sigaction* bionic_old) {
// The 32-bit ABI is broken. struct sigaction includes a too-small sigset_t,
// so we have to translate to struct sigaction64 first.
@@ -101,7 +123,7 @@
}
struct sigaction64 kernel_old;
- int result = sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old);
+ int result = __sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old);
if (bionic_old) {
*bionic_old = {};
bionic_old->sa_flags = kernel_old.sa_flags;
@@ -115,23 +137,7 @@
}
int sigaction64(int signal, const struct sigaction64* bionic_new, struct sigaction64* bionic_old) {
- struct sigaction64 kernel_new;
- if (bionic_new) {
- kernel_new = *bionic_new;
-#if defined(SA_RESTORER)
- if (!(kernel_new.sa_flags & SA_RESTORER)) {
- kernel_new.sa_flags |= SA_RESTORER;
- kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
- }
-#endif
- // Don't filter signals here; if the caller asked for everything to be blocked, we should obey.
- kernel_new.sa_mask = kernel_new.sa_mask;
- }
-
- return __rt_sigaction(signal,
- bionic_new ? &kernel_new : nullptr,
- bionic_old,
- sizeof(kernel_new.sa_mask));
+ return __sigaction64(signal, bionic_new, bionic_old);
}
#endif
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 3241a1e..1139e53 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -244,7 +244,6 @@
ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicui18n.so", RTLD_NOW) != nullptr);
}
-/* TODO: Re-enable test when the cuttlefish build is fixed. http://b/156315785
TEST(dlfcn, dlopen_system_libicuuc_android_api_level_29) {
android_set_application_target_sdk_version(29);
ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicuuc.so", RTLD_NOW) == nullptr);
@@ -255,7 +254,6 @@
ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicuuc.so", RTLD_NOW) == nullptr);
ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicui18n.so", RTLD_NOW) == nullptr);
}
-*/
TEST(dlfcn, dlopen_from_zip_absolute_path) {
const std::string lib_zip_path = "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip";