美文网首页
Android Zygote-2 源码分析 之 SystemSe

Android Zygote-2 源码分析 之 SystemSe

作者: 行走中的3卡 | 来源:发表于2023-07-24 15:37 被阅读0次

    Android 系统三大核心进程: init 、 zygote 、 system_server

    使用 ps -A 可以看到这几个进程信息

    root             1     0 12524552  5668 do_epoll_+          0 S init
    
    root          1322     1 16798980 70176 do_sys_po+          0 S zygote64
    root          1323     1 1836592  21892 do_sys_po+          0 S zygote
    
    system        1879  1322 25091236 450520 do_epoll_+         0 S system_server
    

    下面将从 跟踪 Zygote 到 SystemServer 再到系统核心服务的创建,源码分析加深理解。

    1. ZygoteInit.main 创建及启动 SysteServer进程

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

        @UnsupportedAppUsage
        public static void main(String[] argv) {
                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;
                    }
                }
    

    这里又调用了 forkSystemServer

        private static Runnable forkSystemServer(String abiList, String socketName,
            ...
                /* Request to fork the system server process */
                pid = Zygote.forkSystemServer(
                        parsedArgs.mUid, parsedArgs.mGid,
                        parsedArgs.mGids,
                        parsedArgs.mRuntimeFlags,
                        null,
                        parsedArgs.mPermittedCapabilities,
                        parsedArgs.mEffectiveCapabilities); 
    

    就到了 Zygote 里的处理

    2. Zygote.forkSystemServer()

    这里的逻辑很简单,将调用 native 方法 nativeForkSystemServer

        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;
        }
    

    native的方法是在 com_android_internal_os_Zygote.cpp 文件里实现的

    3. com_android_internal_os_Zygote.nativeForkSystemServer

    frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

    static jint com_android_internal_os_Zygote_nativeForkSystemServer(
      ...     
      pid_t pid = zygote::ForkCommon(env, true,
                                     fds_to_close,
                                     fds_to_ignore,
                                     true);
                                  
      if (pid == 0) {
          // System server prcoess does not need data isolation so no need to
          // know pkg_data_info_list.
          SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
                           effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                           false, nullptr, nullptr, /* is_top_app= */ false,
      else (pid > 0) {
            gSystemServerPid = pid;
            ...
      }
    

    这里看出,两个关键函数 ForkCommon 和 SpecializeCommon, Fork 出一个新的进程.
    pid == 0表示 SystemServer 进程已创建成功了,并把它的 pid 赋值给全局变量 gSystemServerPid

    3.1 ForkCommon

    pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                             const std::vector<int>& fds_to_close,
                             const std::vector<int>& fds_to_ignore,
                             bool is_priority_fork,
                             bool purge) {
        SetSignalHandlers();
        ...
        pid_t pid = fork();
    
    

    SetSignalHandlers() 函数将注册一个信号处理器:SigChldHandler,来监听子进程的死亡。

    4 ZygoteInit.handleSystemServerProcess()

    在1 中 forkSystemServer 函数中调用 Zygote.forkSystemServer 创建 SystemServer 进程后,
    会调用 handleSystemServerProcess 处理SystemServer自己 的工作

        private static Runnable forkSystemServer(String abiList, String socketName,
                /* 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);
            }
    
    

    pid == 0表示 SystemServer 进程已创建成功了,这在它的线程里去处理相关任务.
    它的处理函数为:

        /**
         * Finish remaining work for the newly forked system server process.
         */
        private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
            // set umask to 0077 so new files and directories will default to owner-only permissions.
            Os.umask(S_IRWXG | S_IRWXO);
    
            if (parsedArgs.mNiceName != null) {
                Process.setArgV0(parsedArgs.mNiceName);
            }
    
            final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
            if (systemServerClasspath != null) {
                // Capturing profiles is only supported for debug or eng builds since selinux normally
                // prevents it.
                if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {
                    try {
                        Log.d(TAG, "Preparing system server profile");
                        final String standaloneSystemServerJars =
                                Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
                        final String systemServerPaths = standaloneSystemServerJars != null
                                ? String.join(":", systemServerClasspath, standaloneSystemServerJars)
                                : systemServerClasspath;
                        prepareSystemServerProfile(systemServerPaths);
                    } catch (Exception e) {
                        Log.wtf(TAG, "Failed to set up system server profile", e);
                    }
                }
            }
    
            if (parsedArgs.mInvokeWith != null) {
                String[] args = parsedArgs.mRemainingArgs;
                // If we have a non-null system server class path, we'll have to duplicate the
                // existing arguments and append the classpath to it. ART will handle the classpath
                // correctly when we exec a new process.
                if (systemServerClasspath != null) {
                    String[] amendedArgs = new String[args.length + 2];
                    amendedArgs[0] = "-cp";
                    amendedArgs[1] = systemServerClasspath;
                    System.arraycopy(args, 0, amendedArgs, 2, args.length);
                    args = amendedArgs;
                }
    
                WrapperInit.execApplication(parsedArgs.mInvokeWith,
                        parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                        VMRuntime.getCurrentInstructionSet(), null, args);
    
                throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
            } else {
                ClassLoader cl = getOrCreateSystemServerClassLoader();
                if (cl != null) {
                    Thread.currentThread().setContextClassLoader(cl);
                }
    
                /*
                 * Pass the remaining arguments to SystemServer.
                 */
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, cl);
            }
    
            /* should never reach here */
        }
    

    加载了 SystemServer 对应的文件 systemServerClasspath
    构建对应的 ClassLoader: getOrCreateSystemServerClassLoader
    最后将剩余的参数交给 ZygoteInit.zygoteInit() 完成进程的初始化

    5 ZygoteInit.zygoteInit

    又回到了 一开始的文件

        public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
                String[] argv, ClassLoader classLoader) {
            if (RuntimeInit.DEBUG) {
                Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
            }
    
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
            RuntimeInit.redirectLogStreams();
    
            RuntimeInit.commonInit();
            ZygoteInit.nativeZygoteInit();
            return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                    classLoader);
        }
    

    这里又会进行 native 的调用

    6. AndroidRuntime.cpp -> nativeZygoteInit

    上面的ZygoteInit.nativeZygoteInit()调用,实际上将会进入AndroidRuntime里的实现:
    frameworks/base/core/jni/AndroidRuntime.cpp

    static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        gCurRuntime->onZygoteInit();
    }
    

    这里的 gCurRuntime 是 AppRuntime 。 它的父类是 AndroidRuntime, 创建的时候 赋值 gCurRuntime

    AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
            mExitWithoutCleanup(false),
            mArgBlockStart(argBlockStart),
            mArgBlockLength(argBlockLength)
    {
        init_android_graphics();
    
        // Pre-allocate enough space to hold a fair number of options.
        mOptions.setCapacity(20);
    
        assert(gCurRuntime == NULL);        // one per process
        gCurRuntime = this;
    }
    

    也就是说 gCurRuntime 是 AppRuntime 本身。
    因此,onZygoteInit 也就是 AppRuntime 里实现的

    7. AppRuntime.onZygoteInit

    AppRuntime 类是在 文件 app_main.cpp里的定义的
    frameworks/base/cmds/app_process/app_main.cpp

    class AppRuntime : public AndroidRuntime
    {
        virtual void onZygoteInit()
        {
            sp<ProcessState> proc = ProcessState::self();
            ALOGV("App process: starting thread pool.\n");
            proc->startThreadPool();
        }
    

    onZygoteInit 里又启动一个线程池,用于 binder 通信。这样应用程序进程就在可以在 进程间通信了。

    8. RuntimeInit.applicationInit

    在5 里ZygoteInit.zygoteInit 的最后, 调用 RuntimeInit.applicationInit
    frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

        protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
                String[] argv, ClassLoader classLoader) {
            // If the application calls System.exit(), terminate the process
            // immediately without running any shutdown hooks.  It is not possible to
            // shutdown an Android application gracefully.  Among other things, the
            // Android runtime shutdown hooks close the Binder driver, which can cause
            // leftover running threads to crash before the process actually exits.
            nativeSetExitWithoutCleanup(true);
    
            VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
            VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
    
            final Arguments args = new Arguments(argv);
    
            // The end of of the RuntimeInit event (see #zygoteInit).
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    
            // Remaining arguments are passed to the start class's static main
            return findStaticMain(args.startClass, args.startArgs, classLoader);
        }
    

    再看 findStaticMain, 通过反射的方法,调用了 SystemServer.main 方法
    (如果是普通应用程序,则是 反射 ActivityThread.main 方法)

        protected static Runnable findStaticMain(String className, String[] argv,
                ClassLoader classLoader) {
            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);
            }
    
            /*
             * 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.
             */
            return new MethodAndArgsCaller(m, argv);
        }
    

    9. SystemServer.main

    frameworks/base/services/java/com/android/server/SystemServer.java

        /**
         * The main entry point from zygote.
         */
        public static void main(String[] args) {
            new SystemServer().run();
        }
    

    从注释里看出, main 是从 zygote 的入口。

    10. SystemServer.run

    这里就到了SystemServer的核心逻辑, 创建了 系统的核心服务

        private void run() {
            ...
                // Initialize native services.
                System.loadLibrary("android_servers");  
                
                // Initialize the system context.
                createSystemContext();
    
                // Create the system service manager.
                mSystemServiceManager = new SystemServiceManager(mSystemContext);
    
            // Start services.
            try {
                t.traceBegin("StartServices");
                startBootstrapServices(t);
                startCoreServices(t);
                startOtherServices(t);
                startApexServices(t);
            } catch (Throwable ex) {            
    

    10. 总结.

    (1) Zygote 进程创建出 子进程system_server, 然后 system_server 进程创建系统核心服务。
    (2) Zygote 进程创建 其它 子进程 的过程 类似, 最后 回调的是 应用程序主线程的 ActivityThread.main 方法
    (3) 熟悉这个过程,对深入理解 Android 的 Framework 框架很有帮助,是个很好的切入点.

    11. 参考:

    (结合Zygote)
    https://juejin.cn/post/6850418113059422221
    Android App Process 启动流程攻略 - 掘金 (juejin.cn)
    (这个讲得很不错)

    相关文章

      网友评论

          本文标题:Android Zygote-2 源码分析 之 SystemSe

          本文链接:https://www.haomeiwen.com/subject/zzxcpdtx.html