Zygote
和system_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 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" , "--runtime-args" , "com.android.server.SystemServer" , }; ZygoteConnection.Arguments parsedArgs = null ; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null , parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } if (pid == 0 ) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } 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 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); 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 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) { 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进程也自杀重启 */ 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 private static void handleSystemServerProcess ( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null ) { Process.setArgV0(parsedArgs.niceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH" ); if (systemServerClasspath != null ) { performSystemServerDexOpt(systemServerClasspath); } 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(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 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(); nativeZygoteInit(); 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 private static void invokeStaticMain (String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; try { cl = Class.forName(className, true , classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { 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(); 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 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类的由public
和static
修饰的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 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 () { ...... Looper.prepareMainLooper(); System.loadLibrary("android_servers" ); 由此可知,performPendingShutdown()的调用有可能不会返回这里继续向下执行。*/ performPendingShutdown(); 是把系统主题设置为"android.R.style.Theme_DeviceDefault_Light_DarkActionBar"。*/ createSystemContext(); 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启动的大致流程可以用下图概括: