Android系统启动系列4 SystemServer进程上
发布日期:2021-05-06 20:19:11 浏览次数:14 分类:技术文章

本文共 18063 字,大约阅读时间需要 60 分钟。

一 概述

SystemServer 在 Android 系统中居于非常重要的地位,SystemServer 是 zygote 进程 fork 的第一个进程,进程名为 system_server,它和 zygote 这两个进程顶起了 java 世界的半边天,任何一个进程的死亡,都会导致 java 世界的崩溃。通常我们大多数死机重启问题也是发生在了 system_server 进程中,该进程承载着整个 framework 的核心服务,例如常见的 AMS,WMS,PMS,PowerManagerService 等常见的核心服务都运行在这 system_server 这个进程中.为了防止应用进程对系统造成破坏,应用进程没有权限访问系统的资源,只能通过 SystemServer 进程的代理来访问 Android 系统.

在上一篇介绍 zygote 启动流程的文章中我们知道 zygote 启动过程中会调用 forkSystemServer(),可知 forkSystemServer() 函数是 system_server 启动流程的起点, 启动流程图如下:

在这里插入图片描述

涉及到的源码路徑

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java/frameworks/base/core/java/com/android/internal/os/Zygote.java /frameworks/base/services/java/com/android/server/SystemServer.java/frameworks/base/services/core/java/com/android/serverSystemServiceManager.java/frameworks/base/services/core/java/com/android/ServiceThread.java/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java /frameworks/base/core/java/android/app/ActivityThread.java/frameworks/base/core/java/android/app/LoadedApk.java/frameworks/base/core/java/android/app/ContextImpl.java /frameworks/base/core/jni/AndroidRuntime.cpp/frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp/frameworks/base/cmds/app_process/app_main.cpp

二 架构

SystemServer 被 zygote 进程 fork 出来后,用来创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService 等90多个核心系统服务

在这里插入图片描述

三 源码分析

3.1 ZygoteInit.main

public static void main(String argv[]) {   	ZygoteServer zygoteServer = null;    ...	try {   		zygoteServer = new ZygoteServer(isPrimaryZygote);		if (startSystemServer) {   			//fork system_server			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(); //启动SystemServer.java的main()				return; //Android 8.0之前是通过抛异常的方式来启动,这里是直接return出去,用来清空栈,提高栈帧利用率			}		}        caller = zygoteServer.runSelectLoop(abiList);    } catch (Throwable ex) {           Log.e(TAG, "System zygote died with exception", ex);        throw ex;    } finally {           if (zygoteServer != null) {               zygoteServer.closeServerSocket();        }    }	if (caller != null) {           caller.run();    }	...}

zygote 进程,通过 fork() 函数,最终孵化出 system_server 进程,通过反射的方法启动 SystemServer.java 的 main() 方法

3.2 ZygoteInit.forkSystemServer

private static Runnable forkSystemServer(String abiList, String socketName,        ZygoteServer zygoteServer) {       ........    //参数准备,uid和gid都为1000    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",            "--capabilities=" + capabilities + "," + capabilities,            "--nice-name=system_server",            "--runtime-args",            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,            "com.android.server.SystemServer",    };    ZygoteArguments parsedArgs = null;    int pid;    try {           //将上面准备的参数,按照ZygoteArguments的风格进行封装        parsedArgs = new ZygoteArguments(args);        Zygote.applyDebuggerSystemProperty(parsedArgs);        Zygote.applyInvokeWithSystemProperty(parsedArgs);         //通过fork"分裂"出子进程system_server        pid = Zygote.forkSystemServer(                parsedArgs.mUid, parsedArgs.mGid,                parsedArgs.mGids,                parsedArgs.mRuntimeFlags,                null,                parsedArgs.mPermittedCapabilities,                parsedArgs.mEffectiveCapabilities);    } catch (IllegalArgumentException ex) {           throw new RuntimeException(ex);    }     //进入子进程system_server    if (pid == 0) {           // 处理32_64和64_32的情况        if (hasSecondZygote(abiList)) {               waitForSecondaryZygote(socketName); //需要等待第二个Zygote创建完成        }         // fork时会copy socket,Zygote原有的socket需要关闭        zygoteServer.closeServerSocket();        // system server进程处理自己的工作        return handleSystemServerProcess(parsedArgs);    }    return null;}

准备参数,用来进行 system_server 的 fork,从参数可知,pid=1000,gid=1000,进程名 nick-name = system_server,当有两个 zygote 进程时,需要等待第二个 zygote 创建完成。由于 fork 会拷贝 socket,因此,在 fork 出 system_server 进程后,需要关闭 zygote 进程原有的 socket.

3.3 Zygote.forkSystemServer

public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {       ZygoteHooks.preFork();    // Resets nice priority for zygote process.    resetNicePriority();    //调用native的方法来fork system_server    //最终调用native的方法:com_android_internal_os_Zygote_nativeForkSystemServer    int pid = nativeForkSystemServer(            uid, gid, gids, runtimeFlags, rlimits,            permittedCapabilities, effectiveCapabilities);    // Enable tracing as soon as we enter the system_server.    if (pid == 0) {           Trace.setTracingEnabled(true, runtimeFlags);    }    ZygoteHooks.postForkCommon();    return pid;}

这里的 nativeForkSystemServer() 最终是通过JNI,调用 Nativate C 空间的 com_android_internal_os_Zygote.cpp 文件中对应的com_android_internal_os_Zygote_nativeForkSystemServer() 方法来 fork system_server.

com_android_internal_os_Zygote.cpp

static const JNINativeMethod gMethods[] = {       {    "nativeForkSystemServer", "(II[II[[IJJ)I",      (void *) com_android_internal_os_Zygote_nativeForkSystemServer },}

3.4 nativeForkSystemServer

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) {              pid_t pid = ForkCommon(env, true,                         fds_to_close,                         fds_to_ignore);  if (pid == 0) {         //进入子进程      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,                       permitted_capabilities, effective_capabilities,                       MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,                       false, nullptr, nullptr);  } else if (pid > 0) {         //进入父进程,即zygote进程      ALOGI("System server process %d has been created", pid);       int status;	  //用waitpid函数获取状态发生变化的子进程pid	  //waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了      if (waitpid(pid, &status, WNOHANG) == pid) {   		  //当system_server进程死亡后,重启zygote进程          ALOGE("System server process %d has died. Restarting Zygote!", pid);          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");      }	  ...  }  return pid;}

通过 ForkCommon 进行 fork,pid 返回 0 时,表示当前为 system_server 子进程,当 pid > 0 时,是进入父进程,即 zygote 进程,通过 waitpid 的 WNOHANG 非阻塞方式来监控 system_server 进程挂掉,如果挂掉后重启 zygote 进程。现在使用的 Android 系统大部分情况下是64位的,会存在两个 zygote,当 system_server 挂掉后,只启动 zygote64 这个父进程.

3.5 ForkCommon

static pid_t ForkCommon(JNIEnv* env, bool is_system_server,                        const std::vector
& fds_to_close, const std::vector
& fds_to_ignore) { //设置子进程的signal SetSignalHandlers(); //在fork的过程中,临时锁住SIGCHLD BlockSignal(SIGCHLD, fail_fn); //fork子进程,采用copy on write方式,这里执行一次,会返回两次 //pid=0 表示Zygote fork SystemServer这个子进程成功 //pid > 0 表示SystemServer 的真正的PID pid_t pid = fork(); if (pid == 0) { //进入子进程 PreApplicationInit(); // 关闭并清除文件描述符 // Clean up any descriptors which must be closed immediately DetachDescriptors(env, fds_to_close, fail_fn); ... } else { ALOGD("Forked child process %d", pid); } //fork结束,解锁 UnblockSignal(SIGCHLD, fail_fn); return pid;}

3.6 SpecializeCommon

static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,                             jint runtime_flags, jobjectArray rlimits,                             jlong permitted_capabilities, jlong effective_capabilities,                             jint mount_external, jstring managed_se_info,                             jstring managed_nice_name, bool is_system_server,                             bool is_child_zygote, jstring managed_instruction_set,                             jstring managed_app_data_dir) {     ........  bool use_native_bridge = !is_system_server &&                           instruction_set.has_value() &&                           android::NativeBridgeAvailable() &&                           android::NeedsNativeBridge(instruction_set.value().c_str());   if (!is_system_server && getuid() == 0) {       //对于非system_server子进程,则创建进程组    const int rc = createProcessGroup(uid, getpid());    if (rc == -EROFS) {         ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");    } else if (rc != 0) {         ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));    }  }   SetGids(env, gids, fail_fn);  //设置设置group  SetRLimits(env, rlimits, fail_fn); //设置资源limit   if (use_native_bridge) {       // Due to the logic behind use_native_bridge we know that both app_data_dir    // and instruction_set contain values.    android::PreInitializeNativeBridge(app_data_dir.value().c_str(),                                       instruction_set.value().c_str());  }   if (setresgid(gid, gid, gid) == -1) {       fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));  }   ........   //selinux上下文  if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {       fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",                         uid, is_system_server, se_info_ptr, nice_name_ptr));  }   //设置线程名为system_server,方便调试  if (nice_name.has_value()) {       SetThreadName(nice_name.value());  } else if (is_system_server) {       SetThreadName("system_server");  }   // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).  //设置子进程的signal信号处理函数为默认函数  UnsetChldSignalHandler();   if (is_system_server) {          //对应  Zygote.java 的callPostForkSystemServerHooks()    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);    if (env->ExceptionCheck()) {         fail_fn("Error calling post fork system server hooks.");    } 	//对应ZygoteInit.java 的 createSystemServerClassLoader()	//预取系统服务器的类加载器。这样做是为了尽早地绑定适当的系统服务器selinux域。    env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader);    if (env->ExceptionCheck()) {         // Be robust here. The Java code will attempt to create the classloader      // at a later point (but may not have rights to use AoT artifacts).      env->ExceptionClear();    }	........  }    //等价于调用zygote.java 的callPostForkChildHooks()  env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,                            is_system_server, is_child_zygote, managed_instruction_set);   if (env->ExceptionCheck()) {       fail_fn("Error calling post fork hooks.");  }}

system_server 进程的一些调度配置

3.7 ZygoteInit.handleSystemServerProcess

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {        if (parsedArgs.mNiceName != null) {           Process.setArgV0(parsedArgs.mNiceName); //设置当前进程名为"system_server"    }     final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");    if (systemServerClasspath != null) {          //执行dex优化操作        if (performSystemServerDexOpt(systemServerClasspath)) {               sCachedSystemServerClassLoader = null;        }		........    }     if (parsedArgs.mInvokeWith != null) {           String[] args = parsedArgs.mRemainingArgs;		//如果我们有一个非空系统服务器类路径,我们将不得不复制现有的参数并将类路径附加到它。		//当我们执行一个新进程时,ART将正确地处理类路径。        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 {           // 创建类加载器,并赋予当前线程        createSystemServerClassLoader();        ClassLoader cl = sCachedSystemServerClassLoader;        if (cl != null) {               Thread.currentThread().setContextClassLoader(cl);        }         //system_server进入此分支        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,                parsedArgs.mRemainingArgs, cl);    }}

创建类加载器,并赋予当前线程,其中环境变量 SYSTEMSERVERCLASSPATH,主要是 service.jar、ethernet-service.jar 和 wifi-service.jar 这三个 jar 包.最后调用 ZygoteInit 的 zygoteInit.

3.8 ZygoteInit.zygoteInit

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,        ClassLoader classLoader) {        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");    RuntimeInit.redirectLogStreams();  //重定向log输出     RuntimeInit.commonInit(); //通用的一些初始化    ZygoteInit.nativeZygoteInit(); // zygote初始化    // 应用初始化    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);}

3.8.1 RuntimeInit.commonInit

protected static final void commonInit() {   	LoggingHandler loggingHandler = new LoggingHandler();        // 设置默认的未捕捉异常处理方法    RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);    Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));     // 设置时区,通过属性读出中国时区为"Asia/Shanghai"    RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone"));     //重置log配置    LogManager.getLogManager().reset();    new AndroidConfig();     //设置默认的HTTP User-agent格式,用于 HttpURLConnection    String userAgent = getDefaultUserAgent();    System.setProperty("http.agent", userAgent);     /*     * Wire socket tagging to traffic stats.     */    //设置socket的tag,用于网络流量统计    NetworkManagementSocketTagger.install();	........}

配置 log、时区、http userAgent 等基础信息

3.8.2 ZygoteInit.nativeZygoteInit

int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env){       const JNINativeMethod methods[] = {           {    "nativeZygoteInit", "()V",            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },    };    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",        methods, NELEM(methods));} gCurRuntime = this;static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz){       //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的    gCurRuntime->onZygoteInit();} [app_main.cpp]virtual void onZygoteInit(){       sp
proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); //启动新binder线程}

上一篇介绍 zygote 的启动流程的时候已经介绍过此函数,在此不再赘述.

3.8.3 RuntimeInit.applicationInit

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,        ClassLoader classLoader) {       //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用    nativeSetExitWithoutCleanup(true);     // We want to be fairly aggressive about heap utilization, to avoid    // holding on to a lot of memory that isn't needed.        //设置虚拟机的内存利用率参数值为0.75    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);     final Arguments args = new Arguments(argv);  //解析参数	........    // Remaining arguments are passed to the start class's static main    //调用startClass的static方法 main()     return findStaticMain(args.startClass, args.startArgs, classLoader);}

3.8.4 RuntimeInit.findStaticMain

protected static Runnable findStaticMain(String className, String[] argv,        ClassLoader classLoader) {       Class
cl; try { //拿到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的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); } //把MethodAndArgsCaller的对象返回给ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率 //清除了设置进程所需的所有堆栈帧 return new MethodAndArgsCaller(m, argv);}

拿到 SystemServer 的 main() 方法,并返回 MethodAndArgsCaller() 对象

3.8.5 RuntimeInit.MethodAndArgsCaller

static class MethodAndArgsCaller implements Runnable {       /** method to call */    private final Method mMethod;     /** argument array */    private final String[] mArgs;     public MethodAndArgsCaller(Method method, String[] args) {           mMethod = method;        mArgs = args;    }     public void run() {           try {             //根据传递过来的参数,可知此处通过反射机制调用的是SystemServer.main()方法            mMethod.invoke(null, new Object[] {    mArgs });        } catch (IllegalAccessException ex) {               throw new RuntimeException(ex);        } catch (InvocationTargetException ex) {               Throwable cause = ex.getCause();            if (cause instanceof RuntimeException) {                   throw (RuntimeException) cause;            } else if (cause instanceof Error) {                   throw (Error) cause;            }            throw new RuntimeException(ex);        }    }}

最终在 ZygoteInit.java 的 main(),调用这里的 run() 来启动 SystemServer.java 的 main(),真正进入 SystemServer 进程.

本篇文章讨论到此,我们在下一篇文章中再讨论 SystemServer 是怎么启动系统核心服务的.

上一篇:Android系统启动系列5 SystemServer进程下
下一篇:Android系统启动系列3 zygote进程

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年03月13日 15时15分11秒