ART: Flag to fail thread creation
Add a flag to mark when the zygote is not allowed to create threads.
Bug: 27248115
Bug: 28149511
(cherry picked from commit 415d8070e37c20dfb7e6dc37e74fdb5fffc2022e)
Change-Id: I1dc3620d9e7d0054c672b993d89459fc4b353dfc
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 887eee0..1aa789f 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -209,9 +209,21 @@
}
}
+static void ZygoteHooks_startZygoteNoThreadCreation(JNIEnv* env ATTRIBUTE_UNUSED,
+ jclass klass ATTRIBUTE_UNUSED) {
+ Runtime::Current()->SetZygoteNoThreadSection(true);
+}
+
+static void ZygoteHooks_stopZygoteNoThreadCreation(JNIEnv* env ATTRIBUTE_UNUSED,
+ jclass klass ATTRIBUTE_UNUSED) {
+ Runtime::Current()->SetZygoteNoThreadSection(false);
+}
+
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(ZygoteHooks, nativePreFork, "()J"),
NATIVE_METHOD(ZygoteHooks, nativePostForkChild, "(JIZLjava/lang/String;)V"),
+ NATIVE_METHOD(ZygoteHooks, startZygoteNoThreadCreation, "()V"),
+ NATIVE_METHOD(ZygoteHooks, stopZygoteNoThreadCreation, "()V"),
};
void register_dalvik_system_ZygoteHooks(JNIEnv* env) {
diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc
index 13edd67..a742e81 100644
--- a/runtime/native/java_lang_Thread.cc
+++ b/runtime/native/java_lang_Thread.cc
@@ -47,6 +47,15 @@
static void Thread_nativeCreate(JNIEnv* env, jclass, jobject java_thread, jlong stack_size,
jboolean daemon) {
+ // There are sections in the zygote that forbid thread creation.
+ Runtime* runtime = Runtime::Current();
+ if (runtime->IsZygote() && runtime->IsZygoteNoThreadSection()) {
+ jclass internal_error = env->FindClass("java/lang/InternalError");
+ CHECK(internal_error != nullptr);
+ env->ThrowNew(internal_error, "Cannot create threads in zygote");
+ return;
+ }
+
Thread::CreateNativeThread(env, java_thread, stack_size, daemon == JNI_TRUE);
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index d3454e8..0a65b6b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -204,6 +204,7 @@
implicit_so_checks_(false),
implicit_suspend_checks_(false),
no_sig_chain_(false),
+ force_native_bridge_(false),
is_native_bridge_loaded_(false),
is_native_debuggable_(false),
zygote_max_failed_boots_(0),
@@ -211,9 +212,11 @@
oat_file_manager_(nullptr),
is_low_memory_mode_(false),
safe_mode_(false),
+ dump_native_stack_on_sig_quit_(true),
pruned_dalvik_cache_(false),
// Initially assume we perceive jank in case the process state is never updated.
- process_state_(kProcessStateJankPerceptible) {
+ process_state_(kProcessStateJankPerceptible),
+ zygote_no_threads_(false) {
CheckAsmSupportOffsetsAndSizes();
std::fill(callee_save_methods_, callee_save_methods_ + arraysize(callee_save_methods_), 0u);
interpreter::CheckInterpreterAsmConstants();
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 6a6fdb7..ae25dd1 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -635,6 +635,14 @@
return process_state_ == kProcessStateJankPerceptible;
}
+ void SetZygoteNoThreadSection(bool val) {
+ zygote_no_threads_ = val;
+ }
+
+ bool IsZygoteNoThreadSection() const {
+ return zygote_no_threads_;
+ }
+
private:
static void InitPlatformSignalHandlers();
@@ -856,6 +864,9 @@
// Whether or not we currently care about pause times.
ProcessState process_state_;
+ // Whether zygote code is in a section that should not start threads.
+ bool zygote_no_threads_;
+
DISALLOW_COPY_AND_ASSIGN(Runtime);
};
std::ostream& operator<<(std::ostream& os, const Runtime::CalleeSaveType& rhs);