Commit f38a6618 authored by Andreas Gampe's avatar Andreas Gampe
Browse files

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 415d8070)

Change-Id: I1dc3620d9e7d0054c672b993d89459fc4b353dfc
parent 336dd6a0
......@@ -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) {
......
......@@ -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);
}
......
......@@ -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();
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment