SystemServer接管
forkSystemServer() 只负责产生子进程和 ZygoteArguments;子进程真正成为 SystemServer,要经过 handleSystemServerProcess()。该函数在 fork 后、SystemServer.main() 前执行:设置文件创建掩码,写入进程名,读取 SYSTEMSERVERCLASSPATH,按 profile/invoke-with 条件决定是否 exec wrapper,最后把剩余参数和 classloader 交给 ZygoteInit.zygoteInit()。
1. 子进程初始状态
源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(
ZygoteArguments parsedArgs) {
// 新文件和目录默认只允许 owner 访问。
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName);
}
final String systemServerClasspath =
Os.getenv("SYSTEMSERVERCLASSPATH");umask 在子进程一开始生效,影响 SystemServer 后续创建的文件;它不是 SELinux domain 切换。setArgV0() 把进程名改成 system_server,供 proc、log 和调试工具识别。classpath 来自环境变量,空值并不自动等于错误,后续会走 boot classpath/默认 loader 路径。
2. 服务profile
if (systemServerClasspath != null) {
if (shouldProfileSystemServer()
&& (Build.IS_USERDEBUG || Build.IS_ENG)) {
try {
final String standalone =
Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
final String paths = standalone != null
? String.join(":", systemServerClasspath, standalone)
: systemServerClasspath;
prepareSystemServerProfile(paths);
SystemProperties.set(
"debug.tracing.profile_system_server", "1");
} catch (Exception e) {
Log.wtf(TAG,
"Failed to set up system server profile", e);
}
}
}profile 只在 profilesystemserver 实验开关和 userdebug/eng 构建同时满足时执行;生产 user build 不走该分支。prepareSystemServerProfile() 通过 installd 准备 android 包的 profile,再由 VMRuntime.registerAppInfo() 注册 code paths。profile 初始化失败记录 wtf,但源码继续后续启动,不把性能优化失败等同于 SystemServer 身份或 classpath 失败。
3. Boot profile
if (shouldProfileBootClasspath()) {
try {
SystemProperties.set(
"debug.tracing.profile_boot_classpath", "1");
} catch (RuntimeException e) {
Slog.e(TAG,
"Failed to set debug.tracing.profile_boot_classpath", e);
}
}注释说明 Zygote 因权限限制不能设置该系统属性,必须在已经切换到 SystemServer 的子进程中设置。它与 preloadClasses() 中的 JIT counter 重置不同:前者打开后续 tracing 属性,后者决定预加载后从哪里重新开始统计。
4. invoke-with分支
if (parsedArgs.mInvokeWith != null) {
String[] args = parsedArgs.mRemainingArgs;
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName,
parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
null, args);
throw new IllegalStateException(
"Unexpected return from WrapperInit.execApplication");
}invoke-with 会把 SystemServer 交给 wrapper exec;如果有 classpath,则显式把 -cp 和路径插入 wrapper 参数。正常 wrapper 不应返回,返回本身被视为非法状态。该分支的安全许可已在 SS012 的 applyInvokeWithSecurityPolicy() 检查,本文只解释 fork 后消费者如何使用该参数。
5. 类加载交接
ClassLoader cl = getOrCreateSystemServerClassLoader();
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}
return ZygoteInit.zygoteInit(
parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mEnabledCompatChanges,
parsedArgs.mRemainingArgs,
cl);非 wrapper 路径先创建/缓存 SystemServer classloader,并设置当前主线程 context classloader,再进入 zygoteInit()。parsedArgs.mRemainingArgs 不包含 Zygote 控制选项,专门留给 RuntimeInit/SystemServer。classloader 是 SystemServer 子进程的 Java 类加载 owner;设置 context classloader 后,后续服务启动中的线程和反射代码才能使用正确路径。
6. 交给RuntimeInit
源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java、frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static Runnable zygoteInit(
int targetSdkVersion,
long[] disabledCompatChanges,
long[] enabledCompatChanges,
String[] argv,
ClassLoader classLoader) {
RuntimeInit.commonInit();
return RuntimeInit.applicationInit(
targetSdkVersion, disabledCompatChanges,
enabledCompatChanges, argv, classLoader);
}zygoteInit() 负责 RuntimeInit 的通用初始化和 applicationInit 入口;它并不直接创建 SystemServer 实例。RuntimeInit.applicationInit() 最终根据 argv 找到 com.android.server.SystemServer.main(),返回 Runnable,再由 ZygoteInit.main() 的子进程路径调用 caller.run()。
7. 失败边界与下一篇
- umask/setArgV0:影响文件和进程名,失败通常在 native syscall 或参数阶段暴露;
- profile:仅影响调试/性能采集,准备失败不必然阻止启动;
- classpath/classloader:类找不到会在
zygoteInit/反射阶段失败; - invoke-with:wrapper 不应返回,返回被视为非法状态;
zygoteInit:RuntimeInit 找不到目标 main 或 main 抛异常,SystemServer 不会进入run()。
# 输入 fork 后处理函数,输出 umask、classpath、profile、wrapper 和 zygoteInit。
rg -n "handleSystemServerProcess|SYSTEMSERVERCLASSPATH|prepareSystemServerProfile|mInvokeWith|getOrCreateSystemServerClassLoader|zygoteInit" \
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
# 输入 RuntimeInit 交接,输出 applicationInit 和静态 main 解析。
rg -n "zygoteInit|applicationInit|findStaticMain|SystemServer" \
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java下一篇将展开 zygoteInit() 与 RuntimeInit.applicationInit() 的完整反射链,说明 SystemServer.main 的 classloader、参数和异常处理;不会重复本文的 fork 后环境设置。
