runtime: Initialize native bridge in app-zygote
An app-zygote may be running PreLoad hooks, which may require native-bridged
execution if non-native jni code is involved (testAppZygoteSyscalls needs that).
Test: CtsExternalServiceTestCases
android.externalservice.cts.ExternalServiceTest
testBindExternalServiceWithZygote
Test: CtsSeccompHostTestCases
android.seccomp.cts.SeccompHostJUnit4DeviceTest
testAppZygoteSyscalls
both for Q.sdk_gphone_x86_arm.armeabi-v7a
Bug: 143143718
Bug: 146904103
Change-Id: I53f33183cc3d0bd992344441111a84f4c04533fa
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 8e832b8..482c4ec 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -413,13 +413,6 @@
std::srand(static_cast<uint32_t>(NanoTime()));
}
- if (is_zygote) {
- // If creating a child-zygote, do not call into the runtime's post-fork logic.
- // Doing so would spin up threads for Binder and JDWP. Instead, the Java side
- // of the child process will call a static main in a class specified by the parent.
- return;
- }
-
if (instruction_set != nullptr && !is_system_server) {
ScopedUtfChars isa_string(env, instruction_set);
InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
@@ -427,11 +420,12 @@
if (isa != InstructionSet::kNone && isa != kRuntimeISA) {
action = Runtime::NativeBridgeAction::kInitialize;
}
- runtime->InitNonZygoteOrPostFork(env, is_system_server, action, isa_string.c_str());
+ runtime->InitNonZygoteOrPostFork(env, is_system_server, is_zygote, action, isa_string.c_str());
} else {
runtime->InitNonZygoteOrPostFork(
env,
is_system_server,
+ is_zygote,
Runtime::NativeBridgeAction::kUnload,
/*isa=*/ nullptr,
profile_system_server);
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 32de85a..0dc93c3 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -935,6 +935,7 @@
: NativeBridgeAction::kUnload;
InitNonZygoteOrPostFork(self->GetJniEnv(),
/* is_system_server= */ false,
+ /* is_child_zygote= */ false,
action,
GetInstructionSetString(kRuntimeISA));
}
@@ -999,11 +1000,13 @@
void Runtime::InitNonZygoteOrPostFork(
JNIEnv* env,
bool is_system_server,
+ // This is true when we are initializing a child-zygote. It requires
+ // native bridge initialization to be able to run guest native code in
+ // doPreload().
+ bool is_child_zygote,
NativeBridgeAction action,
const char* isa,
bool profile_system_server) {
- DCHECK(!IsZygote());
-
if (is_native_bridge_loaded_) {
switch (action) {
case NativeBridgeAction::kUnload:
@@ -1016,6 +1019,16 @@
}
}
+ if (is_child_zygote) {
+ // If creating a child-zygote we only initialize native bridge. The rest of
+ // runtime post-fork logic would spin up threads for Binder and JDWP.
+ // Instead, the Java side of the child process will call a static main in a
+ // class specified by the parent.
+ return;
+ }
+
+ DCHECK(!IsZygote());
+
if (is_system_server && profile_system_server) {
// Set the system server package name to "android".
// This is used to tell the difference between samples provided by system server
diff --git a/runtime/runtime.h b/runtime/runtime.h
index fd09dfb..61ca874 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -511,6 +511,7 @@
void InitNonZygoteOrPostFork(
JNIEnv* env,
bool is_system_server,
+ bool is_child_zygote,
NativeBridgeAction action,
const char* isa,
bool profile_system_server = false);