System_server启动过程

Zygotesystem_server是Android系统中最重要的两个进程,任何一个进程的死亡都会导致Java世界的崩溃。
之前在《zygote启动过程》中介绍了zygote的启动过程,本文继续分析system_server启动过程。

《zygote启动过程》中提到,ZygoteInit.main()方法的5个关键步骤中,第③步就是调用startSystemServer(abiList, socketName)来启动system_server进程,startSystemServer()方法代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {

long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
/* 硬编码相关启动参数 */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",//设置进程名为system_server
"--runtime-args",
"com.android.server.SystemServer",//实际启动的类
};
ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

/* fork一个子进程,也就是system_server进程 */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

/* 对于子进程,也就是system_server,进入下面的代码 */
if (pid == 0) {
/* 参考《zygote启动过程》最开头的init.zygote32_64.rc文件,会启动2个zygote,第二个的名字是"zygote_secondary" */
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}

/* 把剩下的工作交给system_server进程处理 */
handleSystemServerProcess(parsedArgs);
}

return true;
}

这段代码通过调用Zygote.forkSystemServer()方法,从zygote进程fork出了system_server进程。那么来看看Zygote.forkSystemServer()方法的细节:

1
2
3
4
5
6
7
8
9
10
11
12
13
//Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities)
{

VM_HOOKS.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}

通过名字就可以看出,nativeForkSystemServer()应该是一个native方法,fork的工作就在这个方法中完成。在fork完成后,系统会记录fork出来的system_server进程的pid,这样一来就可以实现当system_server死亡时通知zygote自杀

这个名为nativeForkSystemServer()的native方法实现在/Users/netease/AndroidSourceCode/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities)
{

/*在这里fork新进程*/
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
if (pid > 0) {
/* zygote进程检查子进程system_server有没有死亡。
如果子进程死亡,则zygote进程也自杀重启 */

ALOGI("System server process %d has been created", pid);
gSystemServerPid = pid;
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}

回到本文开头提到的ZygoteInit. startSystemServer()代码片段,在zygote完成了上面fork子进程system_server的工作后,就会调用handleSystemServerProcess(parsedArgs)方法(注意,此时仍然在zygote进程中)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//ZygoteInit.java
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)

throws ZygoteInit.MethodAndArgsCaller {

/*关闭从zygote进程继承来的socket*/
closeServerSocket();

/*设置umask为0077,这样就保证了新的文件和目录默认都只有拥有者才有权限*/
Os.umask(S_IRWXG | S_IRWXO);

/*设置进程名为system_server*/
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}

final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
}

/*从之前启动system_server的参数列表可以看出,invokeWith为null,会走进else分支*/
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
}

WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}

/*调用RuntimeInit类的zygoteInit方法*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

}

上面这段代码最后会调用RuntimeInit.zygoteInit(),如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {

if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams();

/* 一些常规的初始化,例如:
为虚拟机中所有线程设置默认的UncaughtExceptionHandler;
设置时区相关信息;
设置HttpURLConnection使用的HTTP User-Agent信息 等等 */

commonInit();
/*native层的初始化*/
nativeZygoteInit();
/*一些其他初始化工作,并启动SystemServer类的main()方法*/
applicationInit(targetSdkVersion, argv, classLoader);
}

这段代码最后一句applicationInit(targetSdkVersion, argv, classLoader),它的内部会调用invokeStaticMain()方法,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//RuntimeInit.java
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {

Class<?> cl;

/*这里的className的值为"com.android.server.SystemServer"*/
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}

Method m;
try {
/*找到SystemServer类的main()方法*/
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}

int modifiers = m.getModifiers();
/*判断上面找到的main()方法是不是被"static"和"public"修饰*/
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}


/*
这条throw语句会被ZygoteInit.main()捕获并处理,
处理的效果就是执行SystermServer类的main()方法。
*/

throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

上面的方法最后是一条throw语句,还记得《zygote启动过程》中介绍的ZygoteInit类的main()方法吗,这里thorw的对象会在ZygoteInit类的main()中被捕获,在回顾一下精简的ZygoteInit.main()代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//ZygoteInit.java
public static void main(String argv[]) {
......
try{
......
if (startSystemServer) {
startSystemServer(abiList, socketName);
}

......
} catch (MethodAndArgsCaller caller) {
caller.run();
}
}

可以看到,ZygoteInit.main()在catch到MethodAndArgsCaller对象后,会调用caller.run()方法,这个run()方法实际就是通过反射方式mMethod.invoke(null, new Object[] { mArgs })调用method,也就是调用了前面传入的SystemServer类的由publicstatic修饰的main()方法。

为什么这里要用抛出异常在catch中捕获后利用反射来调用SystemServer的main()方法,而不是在RuntimeInit的invokeStaticMain()方法中直接调用main呢?RuntimeInit.java的注释已经解释的很清楚:让这里throw的对象在ZygoteInit的main中被捕获后再调用SystemServer的main方法,能够使刚刚创建的system_server进程清空它顶部所有因为初始化创建system_server进程而生成的栈帧,因为从ZygoteInit的main走到当前的RuntimeInit.invokeStaticMain()已经进行了很深层次的函数调用,浪费了不少堆栈空间。

前面大量的代码,都是为了让ZygoteInit分裂出的system_server进程能够调用SystemServer的main()方法,代码如下:

1
2
3
4
//SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}

可以看到main方法很简单,就是创建一个SystemServer对象,然后调用这个对象的run()方法,下面再看看run()方法的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
private void run() {
....../*与runtime相关的各种初始化*/

/*初始化主线程的Looper*/
Looper.prepareMainLooper();

/*加载libandroid_servers.so库*/
System.loadLibrary("android_servers");

/* 检查这之前最后次尝试关机的操作是否失败了,如果是,则会重启或关机。
由此可知,performPendingShutdown()的调用有可能不会返回这里继续向下执行。*/

performPendingShutdown();

/* 初始化系统context,主要是设置系统主题,当前版本源码
是把系统主题设置为"android.R.style.Theme_DeviceDefault_Light_DarkActionBar"。*/

createSystemContext();

/*创建SystemServiceManager*/
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

/*启动各种服务*/
try {
/*
启动几个必须随系统启动的服务,包括:
ActivityManagerService、PowerManagerService、LightsService、
DisplayManagerService、PackageManagerService、UserManagerService,
以及启动传感器服务
*/

startBootstrapServices();

/*
启动几个核心服务,包括:
BatteryService、UsageStatsService、WebViewUpdateService等
*/

startCoreServices();

/*
启动其他服务,包括:
AccountManagerService、ContentService、VibratorService、
TelecomLoaderService、CameraService等众多service。
很关键的是,startOtherServices()函数内部启动了Watchdog,用来监控系统的运行状态并在必要时重启系统。
*/

startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}

......

/*进入永久循环*/
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

上面这段跑在system_server进程中的代码负责初始化主线程的Looper,并启动各种重要服务,启动看门狗以在必要时重启系统,由此可以看出systerm_server的重要性。至此,system_server启动完成。

system_server启动的大致流程可以用下图概括:

文章目录