Zygote 启动流程分析

1 zygote 进程的创建

Zygote进程用init进程解析init.rc 文件过程中启动创建,

代码路径:frameworks\base\cmds\app_process\app_main.cpp

 

分析Android.mk 文件发现,zygote进程名最初是app_process


LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	app_main.cpp

LOCAL_SHARED_LIBRARIES := \
	libcutils \
	libutils \
	libbinder \
	libandroid_runtime

LOCAL_MODULE:= app_process

include $(BUILD_EXECUTABLE)

2 app_main.cpp代码流程分析

int main(int argc, const char* const argv[])
{
    // These are global variables in ProcessState.cpp
    mArgC = argc;
    mArgV = argv;

    mArgLen = 0;
    for (int i=0; i<argc; i++) {
        mArgLen += strlen(argv[i]) + 1;
    }
    mArgLen--;


     //AppRuntime 是核心类,大部分工作由它完成
    AppRuntime runtime;
    const char* argv0 = argv[0];

    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // Everything up to '--' or first non '-' arg goes to the vm

    int i = runtime.addVmArguments(argc, argv);

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    const char* parentDir = NULL;
    const char* niceName = NULL;
    const char* className = NULL;

	//这个会改名为zygote
	//init.rc : service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    while (i < argc) {
        const char* arg = argv[i++];
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName = arg + 12;
        } else {
            className = arg;
            break;
        }
    }

    if (niceName && *niceName) {
        setArgv0(argv0, niceName);
        set_process_name(niceName);
    }

    runtime.mParentDir = parentDir;

    if (zygote) {

        //这里是重要功能的开始,调用start函数开始.
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");

		
    } else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}<pre name="code" class="java">/* native public static int forkSystemServer(int uid, int gid,
 *     int[] gids, int debugFlags, long permittedCapabilities,
 *     long effectiveCapabilities);
 */
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        const u4* args, JValue* pResult)
{
    pid_t pid;

    //创建system_server 进程
    pid = forkAndSpecializeCommon(args, true);

    /* The zygote process checks whether the child process has died or not. */
    if (pid > 0) {
        int status;

        LOGI("System server process %d has been created", pid);

        gDvm.systemServerPid = pid;
        /* There is a slight window that the system server process has crashed
         * but it went unnoticed because we haven't published its pid yet. So
         * we recheck here just to make sure that all is well.
         * 这里说了,从一个重复的waitpid,forkAndSpecializeCommon里面也有一个waitpid,
         * 问题来了,假如fork后,子进程的还没有创建,主进程就退出了,这就不好了?
         */
         //父进程等待子进程发出的信号,如果子进程system_server挂掉了,那么zygote进程就自己杀掉自己。
        if (waitpid(pid, &status, WNOHANG) == pid) {
            LOGE("System server process %d has died. Restarting Zygote!", pid);
            kill(getpid(), SIGKILL);
        }
    }
    RETURN_INT(pid);
}

 


上面main函数中最终要的是 AppRuntime runtime类,通过 runtime.start("com.android.internal.os.ZygoteInit",

                startSystemServer ? "start-system-server" : "");

完成主要功能。

 

AppRuntime 类分析:

 

AppRutime 类重载了onStarted 等类,但start函数还是用父亲类的   void start(const char *classname, const char* options);

class AppRuntime : public AndroidRuntime
{
public:
    AppRuntime()
        : mParentDir(NULL)
        , mClassName(NULL)
        , mClass(NULL)
        , mArgC(0)
        , mArgV(NULL)
    {
    }

  virtual void onVmCreated(JNIEnv* env)
    {
        if (mClassName == NULL) {
            return; // Zygote. Nothing to do here.
        }

        /*
         * This is a little awkward because the JNI FindClass call uses the
         * class loader associated with the native method we're executing in.
         * If called in onStarted (from RuntimeInit.finishInit because we're
         * launching "am", for example), FindClass would see that we're calling
         * from a boot class' native method, and so wouldn't look for the class
         * we're trying to look up in CLASSPATH. Unfortunately it needs to,
         * because the "am" classes are not boot classes.
         *
         * The easiest fix is to call FindClass here, early on before we start
         * executing boot class Java code and thereby deny ourselves access to
         * non-boot classes.
         */

 			//这里讲package name中的”.” 替换为”/” ,以符合JNI参数规范
        char* slashClassName = toSlashClassName(mClassName);
        mClass = env->FindClass(slashClassName);
        if (mClass == NULL) {
            LOGE("ERROR: could not find class '%s'\n", mClassName);
        }
        free(slashClassName);

        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
    }

    virtual void onStarted()
    {
        sp<ProcessState> proc = ProcessState::self();
        LOGV("App process: starting thread pool.\n");
        proc->startThreadPool();

        AndroidRuntime* ar = AndroidRuntime::getRuntime();
        ar->callMain(mClassName, mClass, mArgC, mArgV);

        IPCThreadState::self()->stopProcess();
    }

    virtual void onZygoteInit()
    {
    	//这里开始与Binder通信建立了联系
        sp<ProcessState> proc = ProcessState::self();
        LOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

    virtual void onExit(int code)
    {
        if (mClassName == NULL) {
            // if zygote
     IPCThreadState::self()->stopProcess();
        }

        AndroidRuntime::onExit(code);
    }

............
}

继续分析父亲类的AndroidRuntimestart 函数:

/*
 * Start the Android runtime.  This involves starting the virtual machine
 * and calling the "static void main(String[] args)" method in the class
 * named by "className".
 *
 * Passes the main function two arguments, the class name and the specified
 * options string.
 */

//根据前面的调用:          runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");
void AndroidRuntime::start(const char* className, const char* options)
{
    LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
            className != NULL ? className : "(unknown)");

    blockSigpipe();

    /*
     * 'startSystemServer == true' means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    if (strcmp(options, "start-system-server") == 0) {
        /* track our progress through the boot sequence */
        const int LOG_BOOT_PROGRESS_START = 3000;
        LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
                       ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine */

	//(1) 创建虚拟机
    JNIEnv* env;
	///*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;
    if (startVm(&mJavaVM, &env) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */

    //(2) 注册JNI函数
    if (startReg(env) < 0) {
        LOGE("Unable to register all android natives\n");
        return;
    }

    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring optionsStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);

	//创建一个String数组,数量为2,	
    strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
 //给Jstring 变量赋值为传进来的package name 
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);

	//设置第一个数组的值为:com.android.internal.os.ZygoteInit
    env->SetObjectArrayElement(strArray, 0, classNameStr);
	
    optionsStr = env->NewStringUTF(options);

	//设置第二数组值为:start-system-server
    env->SetObjectArrayElement(strArray, 1, optionsStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     创建虚拟机,这个线程会变成虚拟机的主线程,直到虚拟机存在才会返回。
     */
      //将com.android.internal.os.ZygoteInit中的"."变成"/"
      //即变成com/android/internal/os/ZygoteInit   以符合JNI命名规范
    char* slashClassName = toSlashClassName(className);

	
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {

	//找到这个类后就继续找成员函数main方法的Mehtod ID
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {

		//(3 )成功找到main函数,调用它,开始进入了Android 的java 世界大门,也就是说ZYGOTE进程是Android java 世界的盘古。
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);

    LOGD("Shutting down VM\n");
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        LOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        LOGW("Warning: VM did not shut down cleanly\n");
}

总结一下Zygote native 进程做了哪些主要工作:

1 创建虚拟机--startVM

2 注册JNI函数--startReg

3 通过JNI知道Java层的com.android.internal.os.ZygoteInit 类,调用main 函数,进入java 世界。


3 打开Java世界大门

从上面分析可以知道,env->CallStaticVoidMethod(startClass, startMeth, strArray);
将调用com.android.internal.os.ZygoteInit中的main 函数,从而进入了java 世界。

源码路径:frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
下面来分析ZygoteInit类的main 函数:
ZygoteInit.java:
public static void main(String argv[]) {
        try {
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

           // 1 注册zygote 用的socket,建立IPC通信的服务端 
            registerZygoteSocket();
			
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());

		// 2 调用 preloadClasses() preloadResources()这两个函数预加载类和资源
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gc();

            // If requested, start system server directly from Zygote
            if (argv.length != 2) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

		// 3 创建 system server  进程 ,简称SS
            if (argv[1].equals("start-system-server")) {
				
                startSystemServer();
				
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

            Log.i(TAG, "Accepting command socket connections");

            if (ZYGOTE_FORK_MODE) {
                runForkMode();
            } else {

		 // 4 调用此函数  ,这里第一步注册的registerZygoteSocket();相呼应	 
                runSelectLoopMode();
		 
            }

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {

		// 5 很重要的函数,这里会抓到子进程抛出的异常,抛出的异常传来了main方法(java层的com.android.server.SystemServer),
		//  caller.run 执行com.android.server.SystemServer的main方法,这叫盖头换面啊,

		// 这里总结一下zygote到system_server
		// zygote(native)  -> zygoteInit(java)  -> startSystemServer()(java) 
		//->Zygote.forkSystemServer(native) 这里与zygote父进程同生共死
		//->handleSystemServerProcess(parsedArgs)
		//->com.android.server.SystemServer  invoke main.
		
		caller.run();
		
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

  


这里分析一下上面三个关键步骤中的第三个步骤:

创建 system server  进程 ,简称SS

   if (argv[1].equals("start-system-server")) {
				
                startSystemServer();
				
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

分析startSystemServer函数:

/**
     * Prepare the arguments and fork for the system server process.
     * 准备进程参数以及fork一个子进程出来,这个进程就是system_server
     */
    private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

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

            /* Request to fork the system server process */
		//forkSystemServer 这里是一个native 函数,
		//代码路径:dalvik\vm\native\dalvik_system_Zygote.cpp 对于函数为Dalvik_dalvik_system_Zygote_forkSystemServer
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
		//创建了子进程,这里是子进程空间,也就是system_server开始了自己的工作使命
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

startSystemServer函数中创建了一个native 进程system_server ,这里又从java 层进入了native层,分析创建system_server native进程的函数,代码路径:dalvik\vm\native\dalvik_system_Zygote.cpp 对于函数为Dalvik_dalvik_system_Zygote_forkSystemServer


/* native public static int forkSystemServer(int uid, int gid,
 *     int[] gids, int debugFlags, long permittedCapabilities,
 *     long effectiveCapabilities);
 */
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        const u4* args, JValue* pResult)
{
    pid_t pid;

    //创建system_server 进程
    pid = forkAndSpecializeCommon(args, true);

    /* The zygote process checks whether the child process has died or not. */
    if (pid > 0) {
        int status;

        LOGI("System server process %d has been created", pid);

        gDvm.systemServerPid = pid;
        /* There is a slight window that the system server process has crashed
         * but it went unnoticed because we haven't published its pid yet. So
         * we recheck here just to make sure that all is well.
         * 这里说了,从一个重复的waitpid,forkAndSpecializeCommon里面也有一个waitpid,
         * 问题来了,假如fork后,子进程的还没有创建,主进程就退出了,这就不好了?
         */
         //父进程等待子进程发出的信号,如果子进程system_server挂掉了,那么zygote进程就自己杀掉自己。
        if (waitpid(pid, &status, WNOHANG) == pid) {
            LOGE("System server process %d has died. Restarting Zygote!", pid);
            kill(getpid(), SIGKILL);
        }
    }
    RETURN_INT(pid);
}


从上面分析可以知道正在创建子进程的动作在 forkAndSpecializeCommon(args, true)函数里面,分析这个函数:

static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{
    pid_t pid;

    uid_t uid = (uid_t) args[0];
    gid_t gid = (gid_t) args[1];
    ArrayObject* gids = (ArrayObject *)args[2];
    u4 debugFlags = args[3];
    ArrayObject *rlimits = (ArrayObject *)args[4];
    int64_t permittedCapabilities, effectiveCapabilities;

    if (isSystemServer) {
        /*
         * Don't use GET_ARG_LONG here for now.  gcc is generating code
         * that uses register d8 as a temporary, and that's coming out
         * scrambled in the child process.  b/3138621
         */
        //permittedCapabilities = GET_ARG_LONG(args, 5);
        //effectiveCapabilities = GET_ARG_LONG(args, 7);
        permittedCapabilities = args[5] | (int64_t) args[6] << 32;
        effectiveCapabilities = args[7] | (int64_t) args[8] << 32;
    } else {
        permittedCapabilities = effectiveCapabilities = 0;
    }
    if (!gDvm.zygote) {
        dvmThrowIllegalStateException(
            "VM instance not started with -Xzygote");

        return -1;
    }

    if (!dvmGcPreZygoteFork()) {
        LOGE("pre-fork heap failed");
        dvmAbort();
    }

	
	// 设置信号处理函数,这里还没创建子进程。
    setSignalHandler();

    dvmDumpLoaderStats("zygote");


    //终于开始了,创建了一个子进程system_server
pid = fork();



	// pid = 0 子进程创建成功
    if (pid == 0) {
	//子进程空间
        int err;
        /* The child process */

#ifdef HAVE_ANDROID_OS
        extern int gMallocLeakZygoteChild;
        gMallocLeakZygoteChild = 1;

        /* keep caps across UID change, unless we're staying root */
        if (uid != 0) {
            err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);

            if (err < 0) {
                LOGE("cannot PR_SET_KEEPCAPS: %s", strerror(errno));
                dvmAbort();
            }
        }

#endif /* HAVE_ANDROID_OS */

        err = setgroupsIntarray(gids);

        if (err < 0) {
            LOGE("cannot setgroups(): %s", strerror(errno));
            dvmAbort();
        }

        err = setrlimitsFromArray(rlimits);

        if (err < 0) {
            LOGE("cannot setrlimit(): %s", strerror(errno));
            dvmAbort();
        }

        err = setgid(gid);
        if (err < 0) {
            LOGE("cannot setgid(%d): %s", gid, strerror(errno));
            dvmAbort();
        }

        err = setuid(uid);
        if (err < 0) {
            LOGE("cannot setuid(%d): %s", uid, strerror(errno));
            dvmAbort();
        }

        int current = personality(0xffffFFFF);
        int success = personality((ADDR_NO_RANDOMIZE | current));
        if (success == -1) {
          LOGW("Personality switch failed. current=%d error=%d\n", current, errno);
        }

        err = setCapabilities(permittedCapabilities, effectiveCapabilities);
        if (err != 0) {
            LOGE("cannot set capabilities (%llx,%llx): %s",
                permittedCapabilities, effectiveCapabilities, strerror(err));
            dvmAbort();
        }

        /*
         * Our system thread ID has changed.  Get the new one.
         */
        Thread* thread = dvmThreadSelf();
        thread->systemTid = dvmGetSysThreadId();

        /* configure additional debug options */
        enableDebugFeatures(debugFlags);

        unsetSignalHandler();
        gDvm.zygote = false;
        if (!dvmInitAfterZygote()) {
            LOGE("error in post-zygote initialization");
            dvmAbort();
        }
    } else if (pid > 0) {
        /* the parent process */
    }

    return pid;
}

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID
    2)在子进程中,fork返回0
    3)如果出现错误,fork返回一个负值;

    fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,

fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

 

上述函数在fork创建子进程之前,先做了一个设置信号处理函数的动作:setSignalHandler(),根据子进程退出返回的信号来调用信号处理函数,信号处理函数分析:

// 设置信号处理函数,这里还没创建子进程。

    setSignalHandler();

static void setSignalHandler()
{
    int err;
    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));

    sa.sa_handler = sigchldHandler;

    err = sigaction (SIGCHLD, &sa, NULL);

    if (err < 0) {
        LOGW("Error setting SIGCHLD handler: %s", strerror(errno));
    }
}

信号处理函数:

/*
 * This signal handler is for zygote mode, since the zygote
 * must reap its children
 */
static void sigchldHandler(int s)
{
    pid_t pid;
    int status;

   // waitpid(pid_t pid,int * status,int options),暂时停止目前进程的执行,直到有信号来到或子进程结束.
   //这里就是等待子进程system_server结束。
   //参数 pid 为欲等待的子进程识别码,其他数值意义如下:
   //pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。
   //pid=-1 等待任何子进程,相当于 wait()。
   //pid=0 等待进程组识别码与目前进程相同的任何子进程。
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        /* Log process-death status that we care about.  In general it is not
           safe to call LOG(...) from a signal handler because of possible
           reentrancy.  However, we know a priori that the current implementation
           of LOG() is safe to call from a SIGCHLD handler in the zygote process.
           If the LOG() implementation changes its locking strategy or its use
           of syscalls within the lazy-init critical section, its use here may
           become unsafe. */

		//WIFEXITED 来判断子进程是否正常结束才能使用此宏,如果子进程正常结束则为非 0 值.
        if (WIFEXITED(status)) {

		//子进程正常结束,取得子进程 exit()返回的结束代码
            if (WEXITSTATUS(status)) {
		  
                LOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)",
                    (int) pid, WEXITSTATUS(status));
            } else {
                IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) {
                    LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
                        "Process %d exited cleanly (%d)",
                        (int) pid, WEXITSTATUS(status));
                }
            }
			
        } else if (WIFSIGNALED(status)) {  //WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真  
        //子进程因为信号而结束,WTERMSIG取得子进程因信号而中止的信号代码
            if (WTERMSIG(status) != SIGKILL) {
                LOG(LOG_DEBUG, ZYGOTE_LOG_TAG,
                    "Process %d terminated by signal (%d)",
                    (int) pid, WTERMSIG(status));
            } else {
            	//因为 SIGKILL 信号而结束
                IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) {
                    LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
                        "Process %d terminated by signal (%d)",
                        (int) pid, WTERMSIG(status));
                }
            }
#ifdef WCOREDUMP
            if (WCOREDUMP(status)) {
                LOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core",
                    (int) pid);
            }
#endif /* ifdef WCOREDUMP */
        }

        /*
         * If the just-crashed process is the system_server, bring down zygote
         * so that it is restarted by init and system server will be restarted
         * from there.
         */

	//如果死去的进程system_server,zygote 父进程就自己干掉自己。
        if (pid == gDvm.systemServerPid) {
            LOG(LOG_INFO, ZYGOTE_LOG_TAG,
                "Exit zygote because system server (%d) has terminated",
                (int) pid);
            kill(getpid(), SIGKILL);
        }
    }

从上面分析,可以知道,如果子进程被kill了,那么父进程(zygote)也会杀掉自己,从而与system_server做到生死相依。到这里,zygoteInit java)通过JNI创建本地的system_server

进程的过程就完结了,只要system_server没有被干掉,zygote 进程就不会自杀。

 

我们继续回到zygoteInit startSystemServer()创建了system_server进程后,system_server进程会干些什么事情。也就是在条件判断

if(pid >0) {} 的语句里面做了些什么,if(pid>) 的判断一个两处,第一处是本地层fork之后

,第二个处则是java层得到本地层返回的pid之后,这里分析第二处,也就是:

        /* For child process */
        if (pid == 0) {
		//创建了子进程,这里是子进程空间,也就是system_server开始了自己的工作使命
            handleSystemServerProcess(parsedArgs);
        }
可以看到handleSystemServerProcess(parsedArgs) 就是system_server进程要做的主要内容:

    /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();

        // set umask to 0077 so new files and directories will default to owner-only permissions.
        FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);

        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        if (parsedArgs.invokeWith != null) {
			
            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    null, parsedArgs.remainingArgs);
        } else {
            		/*
             * Pass the remaining arguments to SystemServer.
             */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
        }

        /* should never reach here */
    }


从代码分析可以看到又调用了 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);

    public static final void zygoteInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        redirectLogStreams();

	//常规初始化
        commonInit();

	//本地初始化
        zygoteInitNative();

	 // 里面调用了 invokeStaticMain(args.startClass, args.startArgs);
        applicationInit(targetSdkVersion, argv);
    }


zygoteInitNative 是一个native 函数,定义在AndroidRumtime.cpp文件里面:
/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    { "finishInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_finishInit },
    { "zygoteInitNative", "()V",
        (void*) com_android_internal_os_RuntimeInit_zygoteInit },
    { "isComputerOn", "()I",
        (void*) com_android_internal_os_RuntimeInit_isComputerOn },
    { "turnComputerOn", "()V",
        (void*) com_android_internal_os_RuntimeInit_turnComputerOn },
    { "getQwertyKeyboard", "()I",
        (void*) com_android_internal_os_RuntimeInit_getQwertyKeyboard },
};



static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
{

    // static AndroidRuntime* gCurRuntime = NULL; 这是一个全局变量
    //gCurRuntime 在AndroidRuntime 构造时被设置为自己,gCurRuntime=this
    //virtual void onZygoteInit() {};这是一个虚函数,那它应该在AndroidRuntime的子类中实现。
    //zygote 进程中定义了AppRuntime,AppRuntime 又继承于AndoirdRuntime,那么实际调用的
    //就是appRuntime.onZygoteInit();
    gCurRuntime->onZygoteInit();
}

从上分析可以知道实际上是调用了AppRuntime类里面的onZygoteInit函数

AppRuntime类定义在App_main.cpp 文件里面

    virtual void onZygoteInit()
    {
    	//这里开始与Binder通信建立了联系
        sp<ProcessState> proc = ProcessState::self();
        LOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }


 好了,继续分析applicationInit(targetSdkVersion, argv); 函数做了什么,
  private static void applicationInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main
        
        invokeStaticMain(args.startClass, args.startArgs);
    }


 private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

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

        Method m;
        try {
		//找到com.android.server.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);
        }

	//java.lang.Class.getModifiers()这个类或接口的Java语言修饰符返回整数编码。
	//修饰符包括public, protected, private, final, static, abstract 和interface及Java虚拟机的常数,他们应该使用Modifier类的方法进行解码。
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
			//main 方法的修饰必须是public static 
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds  
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
           通过调用exception's run() method来响应这个跑出的异常。
         */

		//抛出了一个异常,很奇怪,按道理找到了main方法,就应该在这里调用main。 
		//这个异常在哪里被截获, 在ZygoteInit.java 的main方法中被截获,注意,现在我们在system_server进程
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

抛出的异常被截获的地方:


 
catch (MethodAndArgsCaller caller) {

		// 5 很重要的函数,这里会抓到子进程抛出的异常,抛出的异常传来了main方法(java层的com.android.server.SystemServer),
		//  caller.run 执行com.android.server.SystemServer的main方法,这叫盖头换面啊,

		// 这里总结一下zygote到system_server
		// zygote(native)  -> zygoteInit(java)  -> startSystemServer()(java) 
		//->Zygote.forkSystemServer(native) 这里与zygote父进程同生共死
		//->handleSystemServerProcess(parsedArgs)
		//->com.android.server.SystemServer  invoke main.
		
		caller.run();
		
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
}

// 这里总结一下zygotesystem_server

// zygote(native)  -> zygoteInit(java)  -> startSystemServer()(java)

//->Zygote.forkSystemServer(native) 这里与zygote父进程同生共死

//->handleSystemServerProcess(parsedArgs)

//->com.android.server.SystemServer  invoke main.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值