Android系统启动系列4 SystemServer进程上

一 概述

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<int>& fds_to_close,
                        const std::vector<int>& 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<ProcessState> 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 是怎么启动系统核心服务的.

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值