Zygote进程及其孵化子进程(system_server及ActivityThread)

Zygote 又init.rc脚本解析启动。以下只考虑 Zygote 的启动而不考虑 init.rc 的解析。已知Zygote 的入口函数是app_main.cpp的main()函数。
一下是涉及到的文件路径

app_main.cpp(.../frameworks/base/cmds/app_process/app_main.cpp)
AndroidRuntime.cpp(.../frameworks/base/core/jni/AndroidRuntime.cpp)
RuntimeInit.java(.../frameworks/base/core/java/com/android/internal/os/RuntimeInit.java)
Zygote.java(../frameworks/base/core/java/com/android/internal/os/Zygote.java)
ZygoteInit.java(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
ZygoteConnection.java(.../frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java)
com_android.internal_os_Zygote.cpp(.../frameworks/base/core/jni/com_android_internal_os_Zygote.cpp)
ZygoteHooks.java(.../libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java);
.../frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){
        ...
        //Android运行时环境
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
        ...
        boolean zygote = false;
        boolean startSystemServer = false;
        boolean application = false;
        String8 niceName;
        String8 className;
        ...
        //根据入参,决定当前程序的行为
        while(i  <  argc)  {
                const char* arg = argv[i++];
                if(strcmp(arg, "--zygote") == 0){ //当前进程是否承载 zygote
                        zygote = true;
                        niceName = ZYGOTE_NICE_NAME;
                } else if(strcmp(arg, "--start-system-server") == 0){ // 是否需要启动system server
                        startSystemServer = true;
                } else if(strcmp(arg, "--application") == 0){ //是否进入独立的程序
                        application = true;
                } else if(strncmp(arg, "--nice-name=",12) ==0){//程序别名
                        niceName.setTo(arg + 12);
                } else if(strncmp(arg, "--",2)!=0) {
                        className.setTo(arg);
                }else{
                        i--;
                        break;
                }
        }
        ...
        if(!className.isEmpty()){
                ...
        }else{
                //将启动 system server 入参
                if(startSystemServer){
                        args.add(String8("start--system-server"));
                }
        }
        ...
        if(zygote){
                //表示要启动 Zygote
                runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
        }else if(className)){
                runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
        }
}
//以 zygote = true 为例,这里的 className 为"com.android.internal.os.ZygoteInit"
//.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
void AndroidRuntime::start(const char* className, const Vertor& options, bool zygote){
        ...
        if(startVm(&mJavaVm, &env, zygote) != 0 ){//启动虚拟机
                return;
        }
        onVmCreate(env);//虚拟机启动后的回调
        ...
        //由 JNI 启动对应的类的入口函数
        char* slashClassName = toSlashClassName(className);
        jclass startClass = env->FindClass(slashClassName);
        if(startClass == NULL){
               ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        }else{
                //入口函数设定为 void static main(String[] args),由 jni 进行调用
                //此时执行ZygoteInit.main()函数
                jmethodId startMeth = env->GetStaticMethodID(startClass,"main",
                        "([Ljava/lang/String;])V");
                if(startMeth == NULL){
                        ALOGE("JavaVM unable to find main() in '%s'\n", className);
                }else{
                        env->CallStaticVoidMethod(startClass, startMeth, strArray);
                }
        }
}

由上面通过 JNI 调用,转到 ZygoteInit.main()函数,同理zygote=false 的时候执行com.android.internal.os.RuntimeInit.main()

(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
public static void main(String argv[]){
        ...
        boolean startSytemServer = false;
        String sockName = "zygote";
        ...
        for( int i = 1; i < argv.length; i++){
                if("start-system-server".equals(argv[i])){
                        startSystemServer = true;//表示需要启动 system server
                }  ...
                ...
        }
        ...
        //注册一个 socket,AMS 通知 Zygote fork 是通过 socket 通信的
        registerZygoteSocket(socketName);
        ...
        preload();//预加载各类资源
        ...
        //第一部分,startSystemServer 为 true,进行 system server的孵化
        if(startSystemServer){
                //启动 system server
                startSystemServer(abList, socketName);
        }
        //第二部分,开启 loop,进行 socket 监听,孵化普通进程
        runSelectLoop(abList);
        closeServerSocket();
}

registerZygoteSocket(socketName)我就先不看了 暂时也不了解 Linux 的socket 通信

//从各个子函数就能得到其作用了
//(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
static void preload(){
              preloadClasses();
              preloadResources();
              preloadOpenGL();
              preloadSharedLibraries();
              preloadTextResources();
              WebViewFactory.prepareWebViewInZygote();
}

这里开始第一部分的研究,就是system server 的孵化。主要关注下startSystemServer(abList,socketName)

(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
private static boolean startSystemServer(String abList,String socketName){
              ...
              String args[] = {
                            "--setuid=1000",
                            "--setgid=1000",
                            "---setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,2032,3001,3002,3003,3006,3007",
                            "--capabilities="+capabilities+","+capabilities,
                            "--nice-name=system_server",
                            "--runtime-args",
                            "com.android.server.SystemServer",
              };
              ...
              //将 args 对应解析
              parsedArgs = new ZygoteConnection.Arguments(args);
              //主流程1,fork 进程
              pid = Zygote.forkSystemServer(
                            parsedArgs.uid, parsedArgs.gid,
                            parsedArgs.gids,
                            parsedArgs.debugFlags,
                            null,
                            parsedArgs.permittedCapabilities,
                            parsedArgs.effectiveCapabilities);
                if(pid ==0){
                                ...
                                //流程2,初始化 system server 进程
                                handleSystemServerProcess(parsedArgs);
                }
}

先分析流程1:
转到 Zygote.java

//.../frameworks/base/core/java/com/android/internal/os/Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
              int[ ][ ] rlimits, long permittedCapabilities, long effectiveCapabilities){
              ...
              int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
              ...
}

native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

兜兜转转走到了 native 方法去了,具体的方法名为com_android_internal_os_Zygote_nativeForkSystemServer

// .../frameworks/base/core/jni/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){
              pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      NULL, NULL);
                ...
}

//注意,从 forkSystemServer 调用的参数is_system_server = true
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                     jint debug_flags, jobjectArray javaRlimits,
                                     jlong permittedCapabilities, jlong effectiveCapabilities,
                                     jint mount_external,
                                     jstring java_se_info, jstring java_se_name,
                                     bool is_system_server, jintArray fdsToClose,
                                     jstring instructionSet, jstring dataDir) {
              pid_t pid = fork();
                ...
                //关键代码
                //从下面的register_com_android_internal_os_Zygote()可以得到
                //gZygoteClass 是"com.android.internal.os.Zygote"
                //gClassPostForkChildHooks 是callPostForkChildHooks(int String)函数
                env->CallStaticVoidMethod(gZygoteClass, gClassPostForkChildHooks, debug_flags, is_system_server ? NULL : instructionSet);
                ...
}

static const char kZygoteClassName[] = "com/android/internal/os/Zygote";

int register_com_android_internal_os_Zygote(JNIEnv* env) {
  gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
  gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
                                                   "(ILjava/lang/String;)V");

  return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
}

当 linux fork 好进程后,又通过 JNI 跳转到 Zygote.java,callPostForkChildHooks主要进行孵化后的一些处理工作,不是这里的重点,略过

    private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();

    private   static void callPostForkChildHooks(int debugFlags, String instructionSet){
    //这里的instructionSet 是 null
    VM_HOOKS.postForkChild(debugFlags, instructionSet);
}

到此流程1分析结束,后分析流程2(handleSystemServerProcess()@ZygoteInit.java)

private static void handleSystemServerProcess(ZygoteConnection.Arguments parseArgs){
                ...
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

进入到 RuntimeInit.java

.../frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader){
                ...
                commonInit();//①
                nativeZygoteInit();//②
                applicationInit(targetSdbVersion, argv, classLoader);//③
}

①通用部分初始化,包括设置默认的uncaught exception handler(具体是RuntimeInit 中的UncaughtHandler 类);为HttpURLConnection准备好默认的 HTTP User-Agent(User Agent 包含了与系统浏览器相关的一系列信息)[我看的是6.0代码,据说6.0已经采用 OkHttp 了,关于 HttpURLConnection 的初始化待定]
②负责本地初始化重点研究,native 实现在 com_android_internal_os_RuntimeInit_nativeZygoteInit@AndroidRuntime.cpp,主要是回调起onZygoteInit@app_main.cpp,调用 startThredPool 开启 Binder 线程池以保证其他进程可以正确访问到 Zygote 所提供的服务。
③程序起点

先来分析③

.../frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){
                ...
                //这里的startClass就是前面的"com.android.server.SystemServer"
                invokeStaticMain(args.startClass, args.startArgs, classLoader);
}


private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader){
              //com.android.server.SystemServer
              Class cl = Class.forName(className, true, classLoader);
              Method m = cl.getMethod("main", new Class[]{String[].class});
              ...
              throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

ZygoteInit.MethodAndArgsCaller 是一个 Exception,在最早调用的 ZygoteInit.java的 main()函数中捕获

try{
                ...
                if(startSystemServer){
                                startSystemServer(abiList, socketName);
                }
                ...
}catch(MethodAndArgsCaller caller){
                caller.run();
}

可以得知,这里是通过捕获异常的方式,调用了run()@ZygoteInit.MethodAndArgsCaller

public void run()@ZygoteInit.MethodAndArgsCaller{
                mMethod.invoke(null, new Object[]{mArgs});
}

由 run()方法进入到 SystemServer.main(String[] args)方法。
到此,第一部分 SystemServer 的启动结束。

第二部分

public static void main(String argv[])@ZygoteInit{
        ...
        runSelectLoop(abiList);
        ....
}

private static void runSelectLoop(String abiList){
        ...
        ArrayList peers = new ArrayList();
        ...
        while(true){
                if(i == 0){
                        ...
                }else {
                        boolean done = peer.get(i).runOnce();
                        ...
                }
        }
}
boolean runOnce()@ZygoteConnection{
        ...
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
        ...
        if(pid ==0 ){
       handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
       }else{
              //主要进行扫尾工作,将子进程加入进程组,正确关闭文件等
              handleParentProc(pid, descriptor, serverPipeFd, parsedArgs);
       }
       ...
}

public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          String instructionSet, String appDataDir) {
        //主要进行堆空间的初始化
        VM_HOOKS.preFork();
        int pid = nativeForkAndSpecialize(
                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                  instructionSet, appDataDir);
        if (pid == 0) {
            ...
        }
        VM_HOOKS.postForkCommon();
        return pid;
    }

//该方法定义在.../frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
  native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          String instructionSet, String appDataDir);
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits,
        jint mount_external, jstring se_info, jstring se_name,
        jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
            rlimits, capabilities, capabilities, mount_external, se_info,
            se_name, false, fdsToClose, instructionSet, appDataDir);
}

//注意 这里 fork 的是普通进程,调用的参数is_system_server = true
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                     jint debug_flags, jobjectArray javaRlimits,
                                     jlong permittedCapabilities, jlong effectiveCapabilities,
                                     jint mount_external,
                                     jstring java_se_info, jstring java_se_name,
                                     bool is_system_server, jintArray fdsToClose,
                                     jstring instructionSet, jstring dataDir) {
              pid_t pid = fork();
                ...
                //关键代码
                //从下面的register_com_android_internal_os_Zygote()可以得到
                //gZygoteClass 是"com.android.internal.os.Zygote"
                //gClassPostForkChildHooks 是callPostForkChildHooks(int String)函数
                env->CallStaticVoidMethod(gZygoteClass, gClassPostForkChildHooks, debug_flags, is_system_server ? NULL : instructionSet);
                ...

这里的主要作用是 fork 一个进程,主要的初始化还是handleChildProc()@ZygoteConnection.java

private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr){
        ...
        if(...){
        }else{
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null);
        }

}

和 system server 的流程大致一样

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){
        ...
        commonInit();
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
}

不同的是,在 system server 的执行流程中,applicationInit 中调用的是SystemServer.main(),那么在普通的 applicationInit()执行的又是哪个类的main()呢,主要还是要要找args.startClass这个变量。往上推,可以得到 args 在runOnce()@ZygoteConnection 中初始化,

boolean runOnce(){
        ...
        String args[];
        Arguments parsedArgs = null;
        ...
        args = readArgumentList();
        ...
        parsedArgs = new Arguments();
}

所以参数的关键在readArgumentList()中

private String[ ] readArgumentList(){
        ...
        String[] result = new String[argc];
        for(int i = 0, i < argc, i++){
                result[i] = mSocketReader.readLine();
        }
        return result;
}

所以这个启动的参数是由 socket 通信带过来的,一般来说是由 ActivityManagerService 利用 socket 通知 zygote 孵化一个新的进程,参数自然就由 ActivityManagerService带过来

private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){
        ...
        if(entryPoint == null) entryPoint = "android.app.ActivityThread";
        ...
        Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdlVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs);
        ...
}

普遍情况下,即 entryPoint = null 的时候,告诉 zygote 在孵化完成进程后,在子进程执行 android.app.ActivityThread.main(String[]) 方法。
于是流程二分析完毕。

由 system server 和普通情况下的进程孵化可以得知,zygote 对于进程孵化的流程大同小异,只是在孵化好子进程后,在子进程执行的是 SystemServer.main(String[])还是 ActivityThread.main(String[])

总结下调用的流程:


流程一:

  • [email protected]//孵化 system server 进程
    • Zygote.forkSystemServer//参数指定com.android.server.SystemServer
    • forkSystemServer@Zygote
      • nativeForkSystemServer@Zygote
    • com_android_internal_os_Zygote_nativeForkSystemServer@com_android_internal_os_Zygote.cpp
      • ForkAndSpecializeCommon(...,isSystemServer = true,...)@com_android_internal_os_Zygote.cpp
    • ForkAndSpecializeCommon(...,isSystemServer = true,...)@com_android_internal_os_Zygote.cpp
      • JNI调用 CallStaticVoidMethod,执行CallPostForkChildHooks@Zygot进程孵化后的一些处理工作
  • 在孵化后的子进程[email protected]
    • RuntimeInit.ZygoteInit()
  • ZygoteInit@RuntimeInit
    • commonInte@RuntimeInit//通用部分初始化
    • nativeZygoteInit@RuntimeInit//关键是开启 Binder 线程池让其他进程可以访问 Zygote 提供的服务
    • applicationInit@RuntimeInit
  • application@RuntimeInit
    • invokeStaticMain@RuntimeInit
  • invokeStaticMain@RuntimeInit
    • throw ZygoteInit.MethodAndArgsCaller//参数是 SystemServer.main(String[]),这里是抛出一个异常,在 main@ZygoteInit 捕获
  • main@ZygoteInit
    • caller.run
  • [email protected]
    • java 层的反射调用method.invoke,执行 SystemServer.main 函数
  • 至此,孵化好system_server 进程后,在其子进程执行 SystemServer.main()函数

流程二:

  • [email protected] //loop,监听 socket 孵化进程
    • runOnce@ZygoteConnection
  • runOnce@ZygoteConnection
    • args = readArgumentList()//获取 socket 传来的参数,一般是AMS 需要孵化新进程的请求,携带参数android.app.ActivityThread
    • Zygote.forkAndSpecialize
  • forkAndSpecialize@Zygote
    • nativeForkAndSpecialize@Zygote
    • com_android_internal_os_Zygote_nativeForkAndSpecialize@com_android_internal_os_Zygote.cpp
      • ForkAndSpecializeCommon(...,is_system_server = false,...)@com_android_internal_os_Zygote.cpp
      • JNI 调用 CallStaticVoidMethod,执行CallPostForkChildHooks@Zygot进程孵化后的一些处理工作
  • 在孵化后的子进程 handleChildProc@ZygoteConnection
    • RuntimeInit.zygoteInit(),关键参数是 android.app.ActivityThread
      • commonInit@RuntimeInit
      • nativeZygoteInit@RuntimeInit
      • applicationInit@RuntimeInit
  • application@RuntimeInit
    • invokeStaticMethod@RuntimeInit
    • throw new ZygoteInit.MethodAndArgsCaller(m, argv)抛出异常在main@ZygoteInit 捕获
  • main@ZygoteInit
    • caller.run()
  • [email protected]
    • 反射调用mMethod.invoke在孵化后的子进程执行Activity.main()

于是就进行了 SystmServer 进程的初始化(入口在 SystemServer.main(String[ ])),同时 socket 监听,一旦有来自 AMS 的进程孵化请求,则孵化子进程,并且在子进程执行 ActivityThread.main(String[ ])进行子进程的初始化

自己画的流程图 略丑


Zygote进程及其孵化子进程(system_server及ActivityThread)_第1张图片
zygote.png

你可能感兴趣的:(Zygote进程及其孵化子进程(system_server及ActivityThread))