当前位置:网站首页>Zygote process

Zygote process

2022-06-23 05:19:00 xhBruce

Zygote process

android12-release
Android The system starts
init process – What have you done


system/core/init/init.cpp
system/core/rootdir/init.rc
frameworks/base/cmds/app_process/app_main.cpp
frameworks/base/core/jni/AndroidRuntime.cpp
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/Zygote.java


Zygote.rc file

Zygote By init process Through analysis init.zygote.rc File ,zygote The corresponding executable program app_process, The corresponding source file is App_main.cpp, The process name is zygote.
 Insert picture description here
init.zygote32.rc file

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

init.zygote64.rc file

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

   Creation is called "zygote" Of service Structure ;
   Create for "socket" communication socketinfo Structure ;
   establish "onrestart" Of action Structure .Zygote Where the process can be restarted .


  Zygote The service will follow main class Start while start ,zygote The corresponding executable file is /system/bin/app_processXX, By calling pid =fork() Create child process , adopt execve(svc->args[0], (char**)svc->args, (char**) ENV), Get into App_main.cpp Of main() function .

init analysis /system/etc/init/hw/init.${ro.zygote}.rc File to start the Zygote process
 Insert picture description here

Zygote The boot process

app_main#main

frameworks/base/cmds/app_process/app_main.cpp

  • strcmp(arg, "--zygote") zygote by true,niceName = ZYGOTE_NICE_NAME distinguish 32 position 、64 Bit system
  • strcmp(arg, "--start-system-server") startSystemServer by true
  • runtime.setArgv0(niceName.string(), true /* setProcName */); Set the process name
  • runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
#if defined(__LP64__)
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64";
static const char ZYGOTE_NICE_NAME[] = "zygote64";
#else
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32";
static const char ZYGOTE_NICE_NAME[] = "zygote";
#endif

int main(int argc, char* const argv[])
{
    
//... ...
    while (i < argc) {
    
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
    
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } 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.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
    
            className.setTo(arg);
            break;
        } else {
    
            --i;
            break;
        }
    }
//... ...
        if (startSystemServer) {
    
            args.add(String8("start-system-server"));
        }
//... ...
    if (!niceName.isEmpty()) {
    
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }
 
    if (zygote) {
    
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
    
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
    
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

AndroidRuntime::start

frameworks/base/core/jni/include/android_runtime/AndroidRuntime.h
frameworks/base/core/jni/AndroidRuntime.cpp

  • primary_zygote = true
  • startVm() Create a start java virtual machine
  • startReg() register_jni_procs in JNI Methods registration
  • env->CallStaticVoidMethod(startClass, startMeth, strArray) here startClass by "com.android.internal.os.ZygoteInit",startMeth by main() Method
  • free(slashClassName) Free the memory space of the corresponding object
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    
//... ...
    /* * 'startSystemServer == true' means runtime is obsolete and not run from * init.rc anymore, so we print out the boot start event here. */
    for (size_t i = 0; i < options.size(); ++i) {
    
        if (options[i] == startSystemServer) {
    
            primary_zygote = true;
           /* 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)));
        }
    }
//... ...
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
    
        return;
    }
    onVmCreated(env);

    /* * Register android functions. */
    if (startReg(env) < 0) {
    
        ALOGE("Unable to register all android natives\n");
        return;
    }
//... ...
    /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
    
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
    
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
    
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
    
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);

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

JNI To Java layer

ZygoteInit.main

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

  • RuntimeInit.preForkInit() in RuntimeInit.enableDdms()
  • startSystemServer = true
  • zygoteServer = new ZygoteServer(isPrimaryZygote) by Zygote register socket
  • forkSystemServer() start-up SystemServer
  • caller = zygoteServer.runSelectLoop(abiList); Enter cycle mode ,Zygote Adopt efficient I/O Multiplexing mechanism , Ensure hibernation without client connection requests or data processing , Otherwise, respond to the client's request .
    public static void main(String[] argv) {
    
        ZygoteServer zygoteServer = null;

        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        try {
    
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
    
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        Runnable caller;
        try {
    
            // Store now for StatsLogging later.
            final long startTime = SystemClock.elapsedRealtime();
            final boolean isRuntimeRestarted = "1".equals(
                    SystemProperties.get("sys.boot_completed"));

            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            RuntimeInit.preForkInit();

            boolean startSystemServer = false;
            String zygoteSocketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
    
                if ("start-system-server".equals(argv[i])) {
    
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
    
                    enableLazyPreload = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
    
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
    
                    zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
    
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
            if (!isRuntimeRestarted) {
    
                if (isPrimaryZygote) {
    
                    FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                            BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,
                            startTime);
                } else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {
    
                    FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                            BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,
                            startTime);
                }
            }

            if (abiList == null) {
    
                throw new RuntimeException("No ABI list supplied.");
            }

            // In some configurations, we avoid preloading resources and classes eagerly.
            // In such cases, we will preload things prior to our first fork.
            if (!enableLazyPreload) {
    
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                        SystemClock.uptimeMillis());
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                        SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            }

            // Do an initial gc to clean up after startup
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();
            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

            bootTimingsTraceLog.traceEnd(); // ZygoteInit

            Zygote.initNativeState(isPrimaryZygote);

            ZygoteHooks.stopZygoteNoThreadCreation();

            zygoteServer = new ZygoteServer(isPrimaryZygote);

            if (startSystemServer) {
    
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
    
                    r.run();
                    return;
                }
            }

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

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
    
            Log.e(TAG, "System zygote died with fatal exception", ex);
            throw ex;
        } finally {
    
            if (zygoteServer != null) {
    
                zygoteServer.closeServerSocket();
            }
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
    
            caller.run();
        }
    }

forkSystemServer

pid = Zygote.forkSystemServer Prepare parameters and fork New process , As can be seen from the above SystemServer The process parameter information is uid=1000,gid=1000, The process name is sytem_server,

    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
    
//... ...
        /* 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,1021,1023,"
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
        ZygoteArguments parsedArgs;
//... ...
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
    
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
    
            if (hasSecondZygote(abiList)) {
    
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

frameworks/base/core/java/com/android/internal/os/Zygote.java

    static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    
        ZygoteHooks.preFork();

        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);

        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

        ZygoteHooks.postForkCommon();
        return pid;
    }

Sequence diagram

 Insert picture description here

原网站

版权声明
本文为[xhBruce]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230225032113.html