赞
踩
###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相关的资源,构成新的应用进程
fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,它们更像兄弟关系,这两个进程共享代码空间,但是数据空间是相互独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程返回错误。可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,它们就开始分别做不同的工作。
到此system_server进程已完成创建的所有工作。
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方法进行循环等待。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。