Android7.0启动SystemServer进程

在分析Android系统进入zygote进程一文中知道SystemServer是系统中非常核心的进程

 

SystemServer在ZygoteInit中进行创建,并且启动起来的.代码位置frameworks/base/core/Java/com/Android/internal/os/ZygoteInit.java

[java]  view plain  copy
  1. if (startSystemServer) {    //根据init中传来的参数可知startSystemServer为true  
  2.     startSystemServer(abiList, socketName);    //启动SystemServer  
  3. }  

[java]  view plain  copy
  1. /** 
  2.  * Prepare the arguments and fork for the system server process. 
  3.  */  
  4. private static boolean startSystemServer(String abiList, String socketName)  
  5.         throws MethodAndArgsCaller, RuntimeException {  
  6. //.......  
  7.     /* Hardcoded command line to start the system server */  
  8.     String args[] = {         //准备启动System Server所需要的参数  
  9.         "--setuid=1000",  
  10.         "--setgid=1000",  
  11.         "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",  
  12.         "--capabilities=" + capabilities + "," + capabilities,  
  13.         "--nice-name=system_server",   //进程的名字为system_server  
  14.         "--runtime-args",  
  15.         "com.android.server.SystemServer",    //包名  
  16.     };  
  17.     ZygoteConnection.Arguments parsedArgs = null;  
  18.   
  19.     int pid;  
  20.   
  21.     try {  
  22.         parsedArgs = new ZygoteConnection.Arguments(args);    //通过ZygoteConnection对参数进行封装  
  23.         ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);  
  24.         ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);  
  25.   
  26.         /* Request to fork the system server process */   
  27.         pid = Zygote.forkSystemServer(    //请求孵化SystemServer进程, 将创建的进程号赋值给pid  
  28.                 parsedArgs.uid, parsedArgs.gid,  
  29.                 parsedArgs.gids,  
  30.                 parsedArgs.debugFlags,  
  31.                 null,  
  32.                 parsedArgs.permittedCapabilities,  
  33.                 parsedArgs.effectiveCapabilities);  
  34.     } catch (IllegalArgumentException ex) {  
  35.         throw new RuntimeException(ex);  
  36.     }  
  37.   
  38.     /* For child process */  
  39.     if (pid == 0) {            //pid=0为zygote的子进程  
  40.         if (hasSecondZygote(abiList)) {  
  41.             waitForSecondaryZygote(socketName);  //等待zygote第二阶段  
  42.         }  
  43.   
  44.         handleSystemServerProcess(parsedArgs);    //运行SystemServer,之后SystemServer就与Zygote分道扬镳,在自己的进程中运行  
  45.     }  
  46.   
  47.     return true;  
  48. }  
下面将分两部分讲解进入SystemServer流程:

1.创建SystemServer进程

2.运行SystemServer进程

创建SystemServer进程

Zygote调用forkSystenServer函数来进行创建SystemServer进程,具体代码位置frameworks/base/core/java/com/android/internal/os/Zygote.java

[java]  view plain  copy
  1. /* @return 0 if this is the child, pid of the child 
  2.  * if this is the parent, or -1 on error. 
  3.  */  
  4. public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,  
  5.         int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {  
  6.     VM_HOOKS.preFork();      //将所有守护进程停止运行  
  7.     int pid = nativeForkSystemServer(     //调用native函数孵化进程  
  8.             uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);  
  9.     // Enable tracing as soon as we enter the system_server.  
  10.     if (pid == 0) {  
  11.         Trace.setTracingEnabled(true);   //进入SystemServer进程,可以输出trace  
  12.     }  
  13.     VM_HOOKS.postForkCommon();   //重新运行各个守护进程  
  14.     return pid;  
  15. }  
  16.   
  17. native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,  
  18.         int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);  

通过JNI调用到native函数中,代码位置frameworks/base/core/com_android_internal_os_Zygote.cpp

[cpp]  view plain  copy
  1. static jint com_android_internal_os_Zygote_nativeForkSystemServer(  
  2.         JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,  
  3.         jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,  
  4.         jlong effectiveCapabilities) {  
  5.   pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,    ///孵化进程  
  6.                                       debug_flags, rlimits,  
  7.                                       permittedCapabilities, effectiveCapabilities,  
  8.                                       MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,  
  9.                                       NULL, NULL);  
  10.   if (pid > 0) {        //pid大于0为父进程, 检查子进程是否已经死掉  
  11.       // The zygote process checks whether the child process has died or not.  
  12.       ALOGI("System server process %d has been created", pid);    //输出SystemServer进程信息  
  13.       gSystemServerPid = pid;  
  14.       // There is a slight window that the system server process has crashed  
  15.       // but it went unnoticed because we haven't published its pid yet. So  
  16.       // we recheck here just to make sure that all is well.  
  17.       int status;  
  18.       if (waitpid(pid, &status, WNOHANG) == pid) {       //判断子进程是否死掉, 如果死掉重启zygote  
  19.           ALOGE("System server process %d has died. Restarting Zygote!", pid);  
  20.           RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");  
  21.       }  
  22.   }  
  23.   return pid;  
  24. }  

调用底层进行fork system server,在JNI中主要通过函数ForkAndSpecializeCommon中调用fork()函数孵化SystemServer进程。

Fork函数其实就是使用Linux调用fork创建进程。如果创建出的进程pid为0,说明新进程为Zygote的子进程,系统会为他设置uid,gid等参数。新创建进程的pid大于0的话,说明该进程为进程SystemServer的进程号,Zygote进程会检查一下该进程有没有died,如果进程died了就会重新启动Zygote进程。SystemServer进程创建完成后,就会重新启动垃圾回收后台进程。之后回到ZygoteInit中,SystemServer进程就与Zygote进程正式分道扬镳,pid=0为子进程,以后的代码都运行在了SystemServer进程中了

[cpp]  view plain  copy
  1. // Utility routine to fork zygote and specialize the child process.  
  2. static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,  
  3.                                      jint debug_flags, jobjectArray javaRlimits,  
  4.                                      jlong permittedCapabilities, jlong effectiveCapabilities,  
  5.                                      jint mount_external,  
  6.                                      jstring java_se_info, jstring java_se_name,  
  7.                                      bool is_system_server, jintArray fdsToClose,  
  8.                                      jstring instructionSet, jstring dataDir) {  
  9.   SetSigChldHandler();  
  10.   
  11. #ifdef ENABLE_SCHED_BOOST  
  12.   SetForkLoad(true);  
  13. #endif  
  14.   
  15.   pid_t pid = fork();    //孵化进程  
  16.   if (pid == 0) {  
  17.     // The child process.  
  18.     gMallocLeakZygoteChild = 1;  
  19.   
  20.     // Clean up any descriptors which must be closed immediately  
  21.     DetachDescriptors(env, fdsToClose);  
  22.   
  23.     // Keep capabilities across UID change, unless we're staying root.  
  24.     if (uid != 0) {  
  25.       EnableKeepCapabilities(env);  
  26.     }  
  27.    //........  
  28.     if (!is_system_server) {  
  29.         int rc = createProcessGroup(uid, getpid());  
  30.         if (rc != 0) {  
  31.             if (rc == -EROFS) {  
  32.                 ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");  
  33.             } else {  
  34.                 ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));  
  35.             }  
  36.         }  
  37.     }  
  38.   
  39.     SetGids(env, javaGids);  
  40.   
  41.     SetRLimits(env, javaRlimits);  
  42.     //...  
  43.     rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);  //设置selinux安全上下文  
  44.     //....  
  45.   } else if (pid > 0) {  
  46.     // the parent process  
  47.   
  48. #ifdef ENABLE_SCHED_BOOST  
  49.     // unset scheduler knob  
  50.     SetForkLoad(false);  
  51. #endif  
  52.   
  53.   }  
  54.   return pid;  
  55. }  
  56. }  // anonymous namespace  

运行SystemServer

根据上文分析创建完成SystemServer后会调用函数handleSystemServerProcess处理,继续其未完成的使命。


当Zygote复制出新的进程时,由于复制出的新进程与Zygote进程共享内存空间,而在Zygote进程中创建的服务端Socket是新进程不需要的,所以新创建的进程需要关闭该Socket服务端。系统会将该进程的名字赋值为system_server,我们可以通过ps命令查看。

[java]  view plain  copy
  1. private static void handleSystemServerProcess(  
  2.         ZygoteConnection.Arguments parsedArgs)  
  3.         throws ZygoteInit.MethodAndArgsCaller {  
  4.   
  5.     closeServerSocket();    //关闭zygote中的socket  
  6.   
  7.     // set umask to 0077 so new files and directories will default to owner-only permissions.  
  8.     Os.umask(S_IRWXG | S_IRWXO);  
  9.   
  10.     if (parsedArgs.niceName != null) {  
  11.         Process.setArgV0(parsedArgs.niceName);  //设置进程的名字  
  12.     }  
  13.   
  14.     final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");  //获取systemServerClasspath  
  15.     if (systemServerClasspath != null) {  
  16.         performSystemServerDexOpt(systemServerClasspath);   //对该路径中的文件做dexopt优化  
  17.     }  
  18.   
  19.     if (parsedArgs.invokeWith != null) {   //invokeWith为空故走else  
  20.         String[] args = parsedArgs.remainingArgs;  
  21.         // If we have a non-null system server class path, we'll have to duplicate the  
  22.         // existing arguments and append the classpath to it. ART will handle the classpath  
  23.         // correctly when we exec a new process.  
  24.         if (systemServerClasspath != null) {  
  25.             String[] amendedArgs = new String[args.length + 2];  
  26.             amendedArgs[0] = "-cp";  
  27.             amendedArgs[1] = systemServerClasspath;  
  28.             System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);  
  29.         }  
  30.   
  31.         WrapperInit.execApplication(parsedArgs.invokeWith,  
  32.                 parsedArgs.niceName, parsedArgs.targetSdkVersion,  
  33.                 VMRuntime.getCurrentInstructionSet(), null, args);  
  34.     } else {  
  35.         ClassLoader cl = null;  
  36.         if (systemServerClasspath != null) {  
  37.             cl = createSystemServerClassLoader(systemServerClasspath,  
  38.                                                parsedArgs.targetSdkVersion);  //为systemServer创建ClassLoader, 让他可以进入平台的私有本地类库  
  39.   
  40.             Thread.currentThread().setContextClassLoader(cl);  
  41.         }  
  42.   
  43.         /* 
  44.          * Pass the remaining arguments to SystemServer. 
  45.          */  
  46.         RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);    //调用到RuntimeInit中  
  47.     }  
  48.   
  49.     /* should never reach here */  
  50. }  
classPath中的内容为systemServerClasspath = /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar三个jar包, 之后会将这三个jar从路径中获取出来,判断是否要进行dexopt优化. 如果需要就调用installer进行优化. apk/jar做dexopt会在后文详细讲解 TODO.

[java]  view plain  copy
  1. /** 
  2.  * Performs dex-opt on the elements of {@code classPath}, if needed. We 
  3.  * choose the instruction set of the current runtime. 
  4.  */  
  5. private static void performSystemServerDexOpt(String classPath) {  
  6.     final String[] classPathElements = classPath.split(":");  //将所需要优化的元素保存在string数组中  
  7.     final InstallerConnection installer = new InstallerConnection();  
  8.     installer.waitForConnection();  
  9.     final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();  
  10.   
  11.     try {  
  12.         String sharedLibraries = "";  
  13.         for (String classPathElement : classPathElements) {  
  14.             // System server is fully AOTed and never profiled  
  15.             // for profile guided compilation.  
  16.             // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?  
  17.             final int dexoptNeeded = DexFile.getDexOptNeeded(  //调用DexFile判断该元素是否要进行dexopt优化  
  18.                     classPathElement, instructionSet, "speed",  
  19.                     false /* newProfile */);  
  20.             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {  //如果返回值不为NO_DEXOPT_NEEDED就进行优化  
  21.                 installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,  
  22.                         dexoptNeeded, 0 /*dexFlags*/"speed"null /*volumeUuid*/,  
  23.                         sharedLibraries);  
  24.             }  
  25.             if (!sharedLibraries.isEmpty()) {  
  26.                 sharedLibraries += ":";  
  27.             }  
  28.             sharedLibraries += classPathElement;  
  29.         }  
  30.     } catch (IOException | InstallerException e) {  
  31.         throw new RuntimeException("Error starting system_server", e);  
  32.     } finally {  
  33.         installer.disconnect();  
  34.     }  
  35. }  

上面工作完成之后, 根据systemServerClasspath创建classLoader, 最后,将启动SystemServer的参数解析完剩余的参数“com.android.server.SystemServer”保存在remainingArgs中,并将参数传入RuntimeInit中。代码位置frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

[java]  view plain  copy
  1. public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)  
  2.         throws ZygoteInit.MethodAndArgsCaller {  
  3.     if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");  
  4.   
  5.     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");  
  6.     redirectLogStreams();   //初始化Android LOG输出流, 并且将system.out, system.err关闭, 将两者重新定向到Android log中       
  7.   
  8.     commonInit();    //初始化运行环境  
  9.     nativeZygoteInit();   //创建BInder线程池  
  10.     applicationInit(targetSdkVersion, argv, classLoader);  
  11. }  
[java]  view plain  copy
  1. private static final native void nativeZygoteInit();  //jni调用  

通过JNI调用到AndroidRuntime.cpp中,代码位置framework/base/core/jni/AndroidRuntime.cpp

[java]  view plain  copy
  1. static AndroidRuntime* gCurRuntime = NULL;  
  2.   
  3. static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)  
  4. {  
  5.     gCurRuntime->onZygoteInit();    //调用onZygoteInit函数  
  6. }  
  7.   
  8. /* 
  9.  * JNI registration. 
  10.  */  
  11. static const JNINativeMethod gMethods[] = {  
  12.     { "nativeFinishInit""()V",  
  13.         (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },  
  14.     { "nativeZygoteInit""()V",  
  15.         (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },   //JNI注册函数, nativeZygoteInit对应的jni函数  
  16.     { "nativeSetExitWithoutCleanup""(Z)V",  
  17.         (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },  
  18. };  
由于app_main.cpp为AndroidRuntime的子类, 所以就调用到app_main中的onZygoteInit函数,具体代码位置frameworks/base/cmds/app_process/app_main.cpp
[cpp]  view plain  copy
  1. virtual void onZygoteInit()  
  2. {  
  3.     sp<ProcessState> proc = ProcessState::self();   //创建ProcessState  
  4.     ALOGV("App process: starting thread pool.\n");  
  5.     proc->startThreadPool();     //启动线程池  
  6. }  
代码位置frameworks/native/libs/binder/ProcessState.cpp

[cpp]  view plain  copy
  1. void ProcessState::startThreadPool()  
  2. {  
  3.     AutoMutex _l(mLock);  
  4.     if (!mThreadPoolStarted) {  
  5.         mThreadPoolStarted = true;  
  6.         spawnPooledThread(true);  //开始孵化线程池  
  7.     }  
  8. }  
  9.   
  10. void ProcessState::spawnPooledThread(bool isMain)  
  11. {  
  12.     if (mThreadPoolStarted) {  //变量为true  
  13.         String8 name = makeBinderThreadName();  //获取binder的name  
  14.         ALOGV("Spawning new pooled thread, name=%s\n", name.string());  
  15.         sp<Thread> t = new PoolThread(isMain);  
  16.         t->run(name.string());   //将binder放入线程池, 运行线程  
  17.     }  
  18. }  
  19.   
  20. String8 ProcessState::makeBinderThreadName() {  
  21.     int32_t s = android_atomic_add(1, &mThreadPoolSeq);  
  22.     pid_t pid = getpid();    //获取进程pid  
  23.     String8 name;  
  24.     name.appendFormat("Binder:%d_%X", pid, s);  //为binder命名  
  25.     return name;  
  26. }  
之后调用applicationInit函数,继续向SystemServer中挺进.

[java]  view plain  copy
  1. private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)  
  2.         throws ZygoteInit.MethodAndArgsCaller {  
  3.     //...........  
  4.     final Arguments args;  
  5.     try {  
  6.         args = new Arguments(argv);    //将argv参数封装到Argument中  
  7.     } catch (IllegalArgumentException ex) {  
  8.         Slog.e(TAG, ex.getMessage());  
  9.         // let the process exit  
  10.         return;  
  11.     }  
  12.   
  13.     // The end of of the RuntimeInit event (see #zygoteInit).  
  14.     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  15.   
  16.     // Remaining arguments are passed to the start class's static main  
  17.     invokeStaticMain(args.startClass, args.startArgs, classLoader);    //args.startClass为com.android.Server.SystemServer  
  18. }  
 在调用入口函数invokeStaticMain之前会将从ZygoteInit中传过来的参数进行处理,将com.android.server.SystemServer赋值给startClass,之后进入进程入口函数:

[java]  view plain  copy
  1. private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)  
  2.         throws ZygoteInit.MethodAndArgsCaller {  
  3.     Class<?> cl;  
  4.   
  5.     try {  
  6.         cl = Class.forName(className, true, classLoader); //通过反射获得SystemServer的class  
  7.     } catch (ClassNotFoundException ex) {  
  8.         throw new RuntimeException(  
  9.                 "Missing class when invoking static main " + className,  
  10.                 ex);  
  11.     }  
  12.   
  13.     Method m;  
  14.     try {  
  15.         m = cl.getMethod("main"new Class[] { String[].class });   //通过反射获取SystemServer的main函数  
  16.     } catch (NoSuchMethodException ex) {  
  17.         throw new RuntimeException(  
  18.                 "Missing static main on " + className, ex);  
  19.     } catch (SecurityException ex) {  
  20.         throw new RuntimeException(  
  21.                 "Problem getting static main on " + className, ex);  
  22.     }  
  23.   
  24.     int modifiers = m.getModifiers();    //获取main函数的修饰符  
  25.     if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {  //如果main函数不是静态公共的将会抛出异常  
  26.         throw new RuntimeException(  
  27.                 "Main method is not public and static on " + className);  
  28.     }  
  29.   
  30.     /* 
  31.      * This throw gets caught in ZygoteInit.main(), which responds 
  32.      * by invoking the exception's run() method. This arrangement 
  33.      * clears up all the stack frames that were required in setting 
  34.      * up the process. 
  35.      */  
  36.     throw new ZygoteInit.MethodAndArgsCaller(m, argv);  //抛出异常到ZygoteInit,并传输参数  
  37. }  
 在函数执行最后抛出MethodAndArgsCaller异常,并在ZygoteInit.main中捕获该异常。这样就可以清除应用程序进程在创建过程中的调用栈。将应用程序入口设置为SystemServer的main函数。
[java]  view plain  copy
  1. public static void main(String argv[]) {  
  2.     //.....  
  3.     try {  
  4.      //.....  
  5.     } catch (MethodAndArgsCaller caller) {  
  6.         caller.run();   //在函数中捕获异常, 并调用MethodAndArgsCaller的run函数  
  7.     } catch (RuntimeException ex) {  
  8.         Log.e(TAG, "Zygote died with exception", ex);  
  9.         closeServerSocket();  
  10.         throw ex;  
  11.     }  
  12. }  
其实MethodAndArgsCaller继承于Exception,并且实现于Runnable.

[java]  view plain  copy
  1. public static class MethodAndArgsCaller extends Exception  
  2.         implements Runnable {  
  3.     /** method to call */  
  4.     private final Method mMethod;   //要去调用的函数  
  5.   
  6.     /** argument array */  
  7.     private final String[] mArgs;   //参数组  
  8.   
  9.     public MethodAndArgsCaller(Method method, String[] args) {  
  10.         mMethod = method;      //构造函数, 将SystemServer的main函数赋值给mMethod  
  11.         mArgs = args;  
  12.     }  
  13.   
  14.     public void run() {  
  15.         try {  
  16.             mMethod.invoke(nullnew Object[] { mArgs });    //执行SystemServer的main函数, 从而进入到SystemServer中  
  17.         } catch (IllegalAccessException ex) {  
  18.             throw new RuntimeException(ex);  
  19.         } catch (IllegalArgumentException ex) {  
  20.             throw new RuntimeException(ex);  
  21.         } catch (InvocationTargetException ex) {  
  22.             Throwable cause = ex.getCause();  
  23.             if (cause instanceof RuntimeException) {  
  24.                 throw (RuntimeException) cause;  
  25.             } else if (cause instanceof Error) {  
  26.                 throw (Error) cause;  
  27.             }  
  28.             throw new RuntimeException(ex);  
  29.         }  
  30.     }  
  31. }  

后文将继续讲解进入SystemServer后系统做了那些事情.
1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值