diff options
-rw-r--r-- | runtime/native/dalvik_system_ZygoteHooks.cc | 12 | ||||
-rw-r--r-- | runtime/native/java_lang_Thread.cc | 9 | ||||
-rw-r--r-- | runtime/runtime.cc | 5 | ||||
-rw-r--r-- | runtime/runtime.h | 11 |
4 files changed, 36 insertions, 1 deletions
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index 887eee0455..1aa789f0c6 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -209,9 +209,21 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, } } +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 13edd67b5b..a742e812f7 100644 --- a/runtime/native/java_lang_Thread.cc +++ b/runtime/native/java_lang_Thread.cc @@ -47,6 +47,15 @@ static jboolean Thread_isInterrupted(JNIEnv* env, jobject java_thread) { 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 d3454e891f..0a65b6b1ff 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -204,6 +204,7 @@ Runtime::Runtime() 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 @@ Runtime::Runtime() 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 6a6fdb79db..ae25dd1c65 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -635,6 +635,14 @@ class Runtime { 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 @@ class Runtime { // 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); |