zygote forkSystemServer及systemServer启动

###zygote forkSystemServer方法
通过上一篇文章我们了解到zygote 在ZygoteInit.java类的main方法中调用forkSystemServer方法

    @UnsupportedAppUsage
    public static void main(String[] argv) {
        ZygoteServer zygoteServer = null;
			....省略部分代码
			//根据环境变量(LocalServerSocket)获取zygote文件描述符并重新创建一个socket,可以从这里看到zygote其实就是一个
			//name为"zygote"的socket用来等待ActivityManagerService来请求zygote来fork出新的应用程序进程
			//所以ActivityManagerService 里启动应用程序(APP),都是由该zygote socket进行处理并fork出的子进程
            zygoteServer = new ZygoteServer(isPrimaryZygote);
			//默认为true,将启动systemServer
            if (startSystemServer) {
				//zygote就是一个孵化器,所以这里直接fork出systemServer
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
				//让SystemServer子进程运行起来
				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.
			//让zygote socket(注意不是systemServer zygote)循环运行
			//等待client 进程来请求调用,请求创建子进程(fork 出子进程(例如等待AMS的请求))
			caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with fatal exception", ex);
            throw ex;
        } finally {
            if (zygoteServer != null) {
				//停止关于systemServer的socket,保留和AMS通信的socket
				//在initNativeState阶段创建了一个和sysemServer通信的socket
				//接着拿到systemServer socket文件描述符重新创建了一个可以和AMS通信的socket(/dev/socket/zygote)
                zygoteServer.closeServerSocket();
            }
        }

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

根据代码我们要找到真正forkserver的地方,代码跟踪如下:

frameworks\base\core\java\com\android\internal\os/ZygoteInit.java
    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        int pid;
            /* Request to fork the system server process */
			//通过jni形式去调用init进程下的fork函数,派生出systemServer进程
			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 */
		//pid==0代表已经运行在子进程(SystemServer)上了
		//代表SystemServer创建成功,创建成功后会关闭该socket
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
			//销毁zygoteServer,保留和AMS通信的socket(runSelectLoop)
			//当SystemServer创建过后,zygoteServerSocket就没有用除了,进行关闭
            zygoteServer.closeServerSocket();
			//处理system server进程初始化工作并启动systemServer进程
			//并启动了一个binder线程池供system server进程和其他进程通信使用
			//最后调用RuntimeInit.applicationInit()执行进程启动自身初始化工作
			//applicationInit()最后是通过反射调用了SystemServer.java的main方法
			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) {
		//停掉守护线程,停掉当前进程的所有的线程,zygote每次fork前调用
		ZygoteHooks.preFork();
		//通过jni去调用nativeForkSystemServer()函数
        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);
		//每次调用preFork()后,都会在子进程上调用postForkChild(),
		//并且都会在父进程和子进程上调用postForkCommon(),
		//子进程调用postForkCommon()在postForkCommon()之后

        ZygoteHooks.postForkCommon();
        return pid;
    }

通过AndroidRuntime.cpp类中注册jni可知 具体执行fork的代码在com_android_internal_os_Zygote.cpp文件中:

static const RegJNIRec gRegJNI[] = {
  		 ...省略部分代码
        REG_JNI(register_com_android_internal_os_Zygote),
        REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
        REG_JNI(register_com_android_internal_os_ZygoteInit),
      ....省略部分代码
};

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 runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {
        //初始化usap相关的vector
  std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
                   fds_to_ignore(fds_to_close);

  fds_to_close.push_back(gUsapPoolSocketFD);

  if (gUsapPoolEventFD != -1) {
    fds_to_close.push_back(gUsapPoolEventFD);
    fds_to_ignore.push_back(gUsapPoolEventFD);
  }

  if (gSystemServerSocketFd != -1) {
      fds_to_close.push_back(gSystemServerSocketFd);
      fds_to_ignore.push_back(gSystemServerSocketFd);
  }

  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.
      //在子进程中进行一些system_server相关配置
      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,
                       /* pkg_data_info_list */ nullptr,
                       /* allowlisted_data_info_list */ nullptr, false, false);
  } else if (pid > 0) {
      // The zygote process checks whether the child process has died or not.
      ALOGI("System server process %d has been created", pid);
      gSystemServerPid = 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.
      int status;
	  //在父进程zygote中使用waitpid()函数以及WNOHANG这个选项,监控子进程的结束情况,
      //监控到system_server进程结束时,需要重启zygote。
      //waitpid()函数参考https://www.cnblogs.com/zhaihongliangblogger/p/6367041.htm
      if (waitpid(pid, &status, WNOHANG) == pid) {
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
      }

      if (UsePerAppMemcg()) {//检测是否挂载了memcg
          // Assign system_server to the correct memory cgroup.
          // Not all devices mount memcg so check if it is mounted first
          // to avoid unnecessarily printing errors and denials in the logs.
          if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
              ALOGE("couldn't add process %d into system memcg group", pid);
          }
      }
  }
  return pid;
}

继续跟踪代码在com_android_internal_os_Zygote.cpp的forkCommon方法里面


// Utility routine to fork a process from the zygote.
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();//为zygote管理子进程配置信号SIGCHLD/SIGHUP

  // Curry a failure function.
  auto fail_fn = std::bind(zygote::ZygoteFailure, env,
                           is_system_server ? "system_server" : "zygote",
                           nullptr, _1);

  // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
  // log, which would result in the logging FDs we close being reopened.
  // This would cause failures because the FDs are not allowlisted.
  //
  // Note that the zygote process is single threaded at this point.
//在fork期间临时阻塞SIGCHLD。SIGCHLD处理程序可能会记录日志,
  BlockSignal(SIGCHLD, fail_fn);//这将导致我们关闭的日志fd被重新打开。会导致失败,因为不允许列出fd

  // Close any logging related FDs before we start evaluating the list of
  // file descriptors.
  __android_log_close();//在开始计算文件描述符列表之前,关闭所有与日志记录相关的fd
  AStatsSocket_close();

  // If this is the first fork for this zygote, create the open FD table,
  // verifying that files are of supported type and allowlisted.  Otherwise (not
  // the first fork), check that the open files have not changed.  Newly open
  // files are not expected, and will be disallowed in the future.  Currently
  // they are allowed if they pass the same checks as in the
  // FileDescriptorTable::Create() above.
  if (gOpenFdTable == nullptr) {//如果这是zygote的第一次fork,则创建一个打开的FD表,验证文件受支持的类型和允许列表
    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
  } else {//如果不是,则检查打开的文件是否没有更改,不希望并且未来会禁止打开新的文件
    gOpenFdTable->Restat(fds_to_ignore, fail_fn);//目标的做法是,如果通过了上面的create检测,则允许打开新的文件
  }

  android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();

  if (purge) {//清除未是哦那个的本机内存,以减少与子进程的错误共享。通过减少与子进程共享的libc_malloc区域的大小
    // Purge unused native memory in an attempt to reduce the amount of false
    // sharing with the child process.  By reducing the size of the libc_malloc
    // region shared with the child process we reduce the number of pages that
    // transition to the private-dirty state when malloc adjusts the meta-data
    // on each of the pages it is managing after the fork.
    mallopt(M_PURGE, 0);//当malloc在fork之后调整它所管理的每个页面上的元数据时,可以减少转换到私有状态的页面数量
  }

  pid_t pid = fork();//核心的fork动作

  if (pid == 0) {//子进程
    if (is_priority_fork) {
      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
    } else {
      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
    }

    // The child process.
    PreApplicationInit();

    // Clean up any descriptors which must be closed immediately
    DetachDescriptors(env, fds_to_close, fail_fn);//通过dup3()函数清除那些需要立即关闭的文件描述符

    // Invalidate the entries in the USAP table.
    ClearUsapTable();//清除usap()进程表

    // Re-open all remaining open file descriptors so that they aren't shared
    // with the zygote across a fork.
    gOpenFdTable->ReopenOrDetach(fail_fn);//重新打开所有剩余的打开的文件描述符,这样它们就不会通过fork与zygote共享

    // Turn fdsan back on.
    android_fdsan_set_error_level(fdsan_error_level);

    // Reset the fd to the unsolicited zygote socket
    gSystemServerSocketFd = -1;
  } else {//父进程
    ALOGD("Forked child process %d", pid);
  }

  // We blocked SIGCHLD prior to a fork, we unblock it here.
  UnblockSignal(SIGCHLD, fail_fn);//fork 结束后打开阻塞,对应上面的BlockSignal()

  return pid;
}

###重点是fork
fork()采用copy on write技术,这是linux创建进程的标准方法,调用一次,返回了两次,返回值有3种类型
1、父进程中,fork返回新创建的子进程的pid
2、子进程中,fork返回0
3、当出现错误时,fork返回负数。(当进程数超过上限或者系统内存不足时会出错)
fork()的主要工作是寻找空闲的进程号pid,然后从父进程拷贝进程信息,例如数据段和代码段,fork()子进程要执行的代码等。Zygote进程是所有Android进程的母体,包括system_server和各个APP进程。zygote利用fork()方法生成新进程,对于新进程A复用Zygote进程本身的资源,再加上新进曾A相关的资源,构成新的应用进程
zygote forkSystemServer及systemServer启动_第1张图片
fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,它们更像兄弟关系,这两个进程共享代码空间,但是数据空间是相互独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程返回错误。可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,它们就开始分别做不同的工作。
到此system_server进程已完成创建的所有工作。

systemServer启动

   private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
     ....省略代码
        /* For child process */
		//pid==0代表已经运行在子进程(SystemServer)上了
		//代表SystemServer创建成功,创建成功后会关闭该socket
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
			//销毁zygoteServer,保留和AMS通信的socket(runSelectLoop)
			//当SystemServer创建过后,zygoteServerSocket就没有用除了,进行关闭
            zygoteServer.closeServerSocket();
			//处理system server进程初始化工作并启动systemServer进程
			//并启动了一个binder线程池供system server进程和其他进程通信使用
			//最后调用RuntimeInit.applicationInit()执行进程启动自身初始化工作
			//applicationInit()最后是通过反射调用了SystemServer.java的main方法
			return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }```

在ZygoteInit.java的forkSystemServer方法里面我们知道Zygote调用forkSystemServer方法返回pid,根据上文得知fork systemServer成功后pid的值为0。代码会执行handleSystemServerProcess方法

```java
 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);//设置当前进程名称为"system_server"
        }

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
			//执行dex优化操作
			performSystemServerDexOpt(systemServerClasspath);
            // 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");
                    prepareSystemServerProfile(systemServerClasspath);
                } 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 */
    }
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();//重定向log输出

        RuntimeInit.commonInit();//初始化运行环境,像日志,网络之类的
        ZygoteInit.nativeZygoteInit();//初始化binder
        //应用初始化
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

在ZygoteInit.zygoteInit方法里面主要做了1、初始化运行环境2、初始化binder 3,初始化application三件事。
根据zygoteInit.zygoteInit方法持续跟踪到RuntimeInit.java类的findStaticMain方法里面
文件目录:frameworks\base\core\java\com\android\internal\os/RuntimeInit.java

protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
			 // 反射拿到SystemServer类,classname =com.android.server.SystemServer
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
			// 反射拿到SystemServer.java的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);
        }

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

根据代码可以看到,通过反射创建systemServer类,调用systemServer类里面的main方法
systemServer.java的具体目录是/frameworks/base/services/java/com/android/server/SystemServer.java代码如下:

    public static void main(String[] args) {
        new SystemServer().run();
    }

在main方法里面会创建systemServer对象并调用run方法。
至此。SystemServer就创建和启动完毕了

总结

可以知道zygote是从rc中启动的,zygote本质上就是一个socket,不会关闭和销毁,而创建zygote时携带的startSystemServer参数会启动systemServer子进程,SystemServer也是通过fork出来的,而底层和上层的交互是通过jni实现的,SystemServer的启动是由zygoteInit通过反射的方式启动SystemServer的main方法。
zygote启动时创建了服务端socket,用于SystemServer的创建,当SystemServer创建完成后则会关闭连接,期间已经调用了runSelectLoop来循环等待AMS及其他进城来请求连接,从而fork出应用程序的socket。服务端socket会在SystemServer进程创建完毕后就关闭,已经没有用处了,等待AMS发来连接将采用runSelectLoop方法进行循环等待。

你可能感兴趣的:(zygote,android)