system_server进程分析

本文详细分析了Android系统中的system_server进程创建过程,从startSystemServer()开始,经过forkSystemServer()、nativeForkSystemServer()的JNI实现,再到forkAndSpecializeCommon()、SetSigChldHandler()和SigChldHandler的信号处理。system_server进程的启动涉及AMS初始化、系统服务加载等关键步骤,其创建过程至关重要,因为它是整个Java世界的基石。一旦system_server异常退出,将导致Android系统崩溃。



一、system_server的创建 1

1.1forkSystemServer()函数 2

1.2nativeForkSystemServer() JNI层实现 3

1.3forkAndSpecializeCommon( ) 4

1.4SetSigChldHandler() 4

1.5SigChldHandler 5

二、handleSystemServerProcess()方法 6

2.1zygoteInit()函数 7

总结 8  

system_server进程

 

system_server属于ApplicationFramework层(框架层)。system_server进程开启时,就会初始化AMS,同时,会加载本地系统的服务库,创建系统上下文Context,创建ActivityThread及开启各种服务等等。而在这之后,就会开启系统的Launcher程序,完成系统界面的加载与显示。

注意,Android中所有系统服务都是由system_server进程启动,如果该进程异常退出,就是整个Java世界的末日。

system_server的启动入口函数是startSystemServer(),它位于ZygoteInit.java中。下面开始依次分析system_server进程:

一、system_server的创建

Path:./frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

入口函数源码如下:

 /**

     * Prepare the arguments and fork for the system server process.

     */

    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)

            throws Zygote.MethodAndArgsCaller, RuntimeException {

            .........

            /* Request to fork the system server process */

            pid = Zygote.forkSystemServer(   //调用fork函数创建子进程system_serve

                    parsedArgs.uid, parsedArgs.gid,

                    parsedArgs.gids,

                    parsedArgs.debugFlags,

                    null,

                    parsedArgs.permittedCapabilities,

                    parsedArgs.effectiveCapabilities);

        } catch (IllegalArgumentException ex) {....... }

        /* For child process */

        if (pid == 0) {   //pid如果为0,说明在子进程system_serve

            if (hasSecondZygote(abiList)) {

                waitForSecondaryZygote(socketName);

            }

            zygoteServer.closeServerSocket();

            handleSystemServerProcess(parsedArgs);

        }

}

说明:startSystemServer()函数主要是通过forkSystemServer()创建子进程;以及在子进程system_server启动后便开始调用handleSystemServerProcess()

1.1forkSystemServer()函数

forkSystemServer()是一个native方法,它所对应的源文件Path:./frameworks/base/core/java/com/android/internal/os/Zygote.java

源码如下所示:

 public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,

            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {

        VM_HOOKS.preFork();

        int pid = nativeForkSystemServer(

                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);

        // Enable tracing as soon as we enter the system_server.

        if (pid == 0) {

            Trace.setTracingEnabled(true); //跟踪子进程

        }

        VM_HOOKS.postForkCommon();

        return pid;

    }

    native private static int nativeForkSystemServer(.....) {

        VM_HOOKS.postForkChild(debugFlags, isSystemServer, instructionSet);

}

 

说明:其中的nativeForkSystemServer()是个native成员函数,其对应的JNI层函数为com_android_internal_os_Zygote_nativeForkSystemServer

1.2nativeForkSystemServer() JNI层实现

Path:./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 debug_flags, jobjectArray rlimits, jlong permittedCapabilities,

        jlong effectiveCapabilities) {

//间接调用ForkAndSpecializeCommon()函数

  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) {

      // The zygote process checks whether the child process has died or not.

      ALOGI("System server process %d has been created", pid);

      gSystemServerPid = pid;

      int status;

      if (waitpid(pid, &status, WNOHANG) == pid) {

          ALOGE("System server process %d has died. Restarting Zygote!", pid);

      //从这里可以看出zygote进程和system_server进程同生死

          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");

      }

  }

  return pid;   //返回进程的id

}

 

上述方法会检查System_server子进程是否启动成功,它的启动实际由forkAndSpecializeCommon方法实现。

1.3forkAndSpecializeCommon( )

Path:/home/android/3710/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

forkAndSpecializeCommon方法中,创建了子进程,并返回了子进程id,接下来检查如果system_server进程是否退出,若是的话则zygote进程也将会被被干掉.其实职责就是监听system_server是否存在。

 

// Utility routine to fork zygote and specialize the child process.

static pid_t ForkAndSpecializeCommon(J.......) {

  SetSigChldHandler(); //设置信号处理函数

  sigset_t sigchld;

  sigemptyset(&sigchld);

  sigaddset(&sigchld, SIGCHLD);

  // M: Tracking for flow of zygote forking process

  ALOGI("%s: Begin to fork a new process",__FUNCTION__);

  pid_t pid = fork();  //调用fork()创建进程

  ............

}

说明:在通过fork()创建子进程之前,通过SetSigChldHandler()设置信号处理函数。

1.4SetSigChldHandler()

static void SetSigChldHandler() {

  struct sigaction sa; //Lihnux注册处理信号的一般流程,sigaction 处理SIGCHLD信号,子进程退出信号

  memset(&sa, 0, sizeof(sa));

  sa.sa_handler = SigChldHandler;

  int err = sigaction(SIGCHLD, &sa, NULL);

  if (err < 0) {

    ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));

  }

}

当子进程退出的时候,由SigChldHandler来处理该信号。

1.5SigChldHandler

// This signal handler is for zygote mode, since the zygote must reap its children

static void SigChldHandler(int /*signal_number*/) {

  pid_t pid;

  int status;

  int saved_errno = errno;

  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {  //wait()系列的函数是父进程调用来收集子进程信息的函数

    if (WIFEXITED(status)) {

      if (WEXITSTATUS(status)) {

        ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));

      }

    } else if (WIFSIGNALED(status)) {

      if (WTERMSIG(status) != SIGKILL) {

        ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));

      }

      if (WCOREDUMP(status)) {

        ALOGI("Process %d dumped core.", pid);

      }

    }

    if (pid == gSystemServerPid) {

      ALOGE("Exit zygote because system server (%d) has terminated", pid);

      kill(getpid(), SIGKILL);

    }

  }

  if (pid < 0 && errno != ECHILD) {

    ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));

  }

  errno = saved_errno;

}

 

说明:函数waitpid()中的参数-1表示:等待任何子进程;status:表示子进程退出时候的状态;WNOHANG:表示如果没有子进程退出,不必阻塞。从上面的ALOGW可以很清晰的知道它对不同情况下的处理方法。

 

至此,system_server进程就已经完成创建了。

二、handleSystemServerProcess()方法

system_server进程启动起来之后,开始调用handleSystemServerProcess()方法。该方法位于path: ./frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中,主要做一些清理和初始化的工作,完成system-serve进程的使命。

 

    /**

     * Finish remaining work for the newly forked system server process.

     */

    private static void handleSystemServerProcess(

            ZygoteConnection.Arguments parsedArgs)

            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();  //关闭从zygote进程继承来的socket

        // set umask to 0077 so new files and directories will default to owner-only permissions.

        Os.umask(S_IRWXG | S_IRWXO);

        if (parsedArgs.niceName != null) {

            Process.setArgV0(parsedArgs.niceName); //设置一些进程的参数

        }

       //加载进程对应的文件

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");

        if (systemServerClasspath != null) {

            performSystemServerDexOpt(systemServerClasspath);

        }

        if (parsedArgs.invokeWith != null) {   //根据invoke参数会执行一个Shell命令

            String[] args = parsedArgs.remainingArgs;

            // 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(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);

            }

            WrapperInit.execApplication(parsedArgs.invokeWith,

                    parsedArgs.niceName, parsedArgs.targetSdkVersion,

                    VMRuntime.getCurrentInstructionSet(), null, args);

        } else {

        //利用systemServerClass对应的路径构建对应的ClassLoader

            ClassLoader cl = null;

            if (systemServerClasspath != null) {

                cl = createSystemServerClassLoader(systemServerClasspath,

                        parsedArgs.targetSdkVersion);

                Thread.currentThread().setContextClassLoader(cl);

            }

            /*

             * Pass the remaining arguments to SystemServer.

           //将剩余参数及classLoader递交给RuntimeInitzygoteInit函数

             */

            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);

        }

    }

2.1zygoteInit()函数

接下来的流程进入到RuntimeInit中的zygoteInit函数。zygoteInit函数将根据classLoader和参数,完成不同进程所需要的初始化工作(SystemServer进程与zygote的其它子进程均将使用zygoteInit函数)。

 

Path:./frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

        throws ZygoteInit.MethodAndArgsCaller {

        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");

        redirectLogStreams();   //重定向标准I/O操作

        commonInit();         //初始化一些通用的设置

        nativeZygoteInit();      //开启Binder通信

        applicationInit(targetSdkVersion, argv, classLoader); //虚拟机设置并转换参数

    }

说明:上述标注红色字体的方法是zygoteinit()函数封装了对四个方法的调用实现它的职责。注意在zygoteinit函数里面它会抛出一个异常MethodAndArgsCaller;另外捕获这个异常是在main()函数中实现。(这个main函数会启动一些列服务)

MethodAndArgsCaller比较特殊,它既是一个异常类也是一个线程;当捕获到这个异常之后,都会执行它的run()方法。

而在main()函数启动服务之前,首先要初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等。这个过程涉及到的内容还是挺多的,后续再专门写篇关于SystemServer启动系统服务过程的文章吧。

 

总结system_server进程大致分成两个过程:线程的创建——fork();履行进程的职责handleSystemProcess()。上述的分析就是根据这两个方向去解析system_server进程的。

用张思维导图展示一下大致的流程,如下所示

                       

1.system_server进程

为了获取 Android 系统中 `system_server` 进程的堆栈信息,可以通过 `adb` 命令结合系统工具实现。`system_server` 是 Java 世界中系统服务的宿主进程,其堆栈信息对于调试系统服务启动、线程阻塞等问题非常关键[^1]。 ### 获取 system_server 进程的 PID 首先,需要获取 `system_server` 进程的 PID(进程 ID)。可以使用如下命令: ```bash adb shell ps | grep system_server ``` 输出结果中将包含 `system_server` 的 PID。 ### 使用 jstack 获取 Java 堆栈信息 从 Android 8.0(API 26)开始,系统支持使用 `jstack` 命令来获取 Java 线程的堆栈信息。执行如下命令: ```bash adb shell jstack -p <pid> ``` 其中 `<pid>` 替换为上一步获取到的 `system_server` 进程 ID。该命令会输出当前 `system_server` 进程中所有 Java 线程的堆栈信息,可用于分析线程状态、阻塞点等问题[^1]。 ### 使用 dumpsys 获取系统服务状态 如果需要分析 `system_server` 中系统服务的运行状态,可以使用如下命令: ```bash adb shell dumpsys ``` 该命令会输出所有系统服务的当前状态信息,包括与 `system_server` 相关的服务对象、线程状态等[^3]。 ### 使用 logcat 查看异常堆栈 如果 `system_server` 进程发生了异常(如 ANR 或崩溃),堆栈信息会被记录在 `logcat` 中。可以使用如下命令查看异常日志: ```bash adb logcat -b crash ``` 或者过滤错误级别日志: ```bash adb logcat *:E ``` 这将显示错误级别的日志,并通常包含导致 `system_server` 崩溃的 Java 异常堆栈信息。 ### 使用 ANR 日志分析 如果 `system_server` 进程发生了 ANR(Application Not Responding),系统会自动生成 ANR 日志,包含详细的 Java 堆栈信息。这些日志保存在 `/data/anr/` 目录下,可以通过如下命令导出: ```bash adb pull /data/anr/traces.txt ``` 该文件中记录了发生 ANR 时的线程堆栈信息,可用于分析 `system_server` 中系统服务的响应状态。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值