Android6.0 SystemServer进程

本文详细解析了Android 6.0中SystemServer进程的启动过程,包括从Zygote进程分裂、注册信号处理器、启动核心服务等方面。SystemServer进程在Android系统中的重要性,以及其主要工作内容,如初始化、Binder通信等。此外,还对比了SystemServer与其他进程的启动差异。
摘要由CSDN通过智能技术生成

背景
SystemServer进程是zygote进程启动后,主动“分裂”的第一个进程。
它负责启动大量的Android系统核心服务,其重要性不言而喻。一旦该进程崩溃,整个Android系统将重新启动。

版本
Android 6.0

一、启动SystemServer进程
在分析zygote进程时,我们知道当zygote进程进入到java世界后,在ZygoteInit.java中,将调用startSystemServer函数启动SystemServer进程,其关键代码是:

pid = Zygote.forkSystemServer(
	parsedArgs.uid, parsedArgs.gid,
	parsedArgs.gids,
	parsedArgs.debugFlags,
	null,
	parsedArgs.permittedCapabilities,
	parsedArgs.effectiveCapabilities);

其中,函数forkSystemServer函数定义于Zygote.java中。

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
	..................
	int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
	..................
}

容易看出,该函数通过调用native方法,完成实际的创建操作。
该Native方法定义于frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中。
我们来看看对应的native函数。

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
        jlong effectiveCapabilities) {

  //进行实际的“分裂”工作
  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      NULL, NULL);

  if (pid > 0) {
      //这里SystemServer进程已经创建出来,pid > 0 说明在父进程中
      //将子进程SystemServer的pid存在zygote进程的全局变量中
      gSystemServerPid = pid;

      int status;
      //小概率,SystemServer进程刚创建,就crash;此时需要重启zygote
      if (waitpid(pid, &status, WNOHANG) == pid) {
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env);
      }
  }
  return pid;
}

上述代码中,实际的“分裂”工作,由函数ForAndSpecializeCommon完成。

static pid_t ForkAndSpecializeCommon(......) {
  //注册信号监听器
  SetSigChldHandler();
  ..........
  pid_t pid = fork();
  if (pid == 0) {
	  //根据传入参数进行对应的处理,例如设置进程名,设置各种id(用户id,组id)等
	  ........
	  //反注册掉信号监听器
	  UnsetSigChldHandler();
	  ......
  } else if () {
	  .......
  }

  return pid;

从上面的代码可以看出,ForkAndSpecializeCommon最终是通过fork的方式,分裂出子进程。
这里需要关注一下的是,在zygote进程fork之前,调用SetSigChldHandler函数注册了一个子进程信号监听器。由于子进程共享父进程中的堆及栈信息,因此在子进程中也会有相应的信号处理器。
为了避免该信号监听器对子进程的影响,可以看到在子进程中进行了UnsetSigChldHandler的操作。

接下来,我们看看SetSigChldHandler进行了哪些操作。

static void SetSigChldHandler() {
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = SigChldHandler;
  //该信号监听器关注子进程结束,对应的处理函数为SigChldHandler
  int err = sigaction(SIGCHLD, &sa, NULL);
  if (err < 0) {
    ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
  }
}

从上面的代码可以看出,SetSigChldHandler函数将注册一个信号处理器,来监听子进程的死亡。当子进程死亡后,利用SigChldHandler进行操作。需要注意的是,zygote的信号监听器,关注的是zygote所有的子进程,而不只是SystemServer进程(每次创建一个新的进程时,zygote都会注册对应的监听器)。

SigChldHandler中的重要代码如下所示:

static void SigChldHandler(int /*signal_number*/) {
	.......
	//监听的pid为-1,表示监听任何子进程结束
	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
		//通过status判断子进程结束的原因,并打印相应的log
		........
		//上文已经介绍过,gSystemServerPid中记录了SystemServer的pid
		if (pid == gSystemServerPid) {
		    ALOGE("Exit zygote because system server (%d) has terminated", pid);
		    //如果结束的子进程为SystemServer, zygote也将结束自己
		    kill(getpid(), SIGKILL);
	    }
	}
	.........
}

这里的问题是,所有zygote的子进程中,zygote只关心了Sys

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值