4.3.1 SystemServer的诞生
最后更新于:2022-04-02 05:49:08
我们先回顾一下SS是怎么创建的。
~~~
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,
3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
parsedArgs = new ZygoteConnection.Arguments(args);
intdebugFlags = parsedArgs.debugFlags;
pid = Zygote.forkSystemServer( //调用forkSystemServer
parsedArgs.uid,parsedArgs.gid,
parsedArgs.gids,debugFlags, null);
~~~
从上面的代码中可以看出,SS是由Zygote通过Zygote.forkSystemServer函数fork诞生出来的。这里会有什么玄机吗?先来一起看看forkSystemServer的实现。它是一个native函数,实现在dalvik_system_Zygote.c中,如下所示:
**dalvik_system_Zygote.c**
~~~
static voidDalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_tpid;
//根据参数,fork一个子进程
pid =forkAndSpecializeCommon(args);
if (pid > 0) {
int status;
gDvm.systemServerPid = pid;//保存system_server的进程id
//函数退出前须先检查刚创建的子进程是否退出了。
if(waitpid(pid, &status, WNOHANG) == pid) {
//如果system_server退出了,Zygote直接干掉了自己
//看来Zygote和SS的关系异常紧密,简直是生死与共!
kill(getpid(), SIGKILL);
}
}
RETURN_INT(pid);
}
~~~
下面,再看看forkAndSpecializeCommon,代码如下所示:
**dalvik_system_Zygote.c**
~~~
static pid_t forkAndSpecializeCommon(const u4*args)
{
pid_tpid;
uid_tuid = (uid_t) args[0];
gid_tgid = (gid_t) args[1];
ArrayObject* gids = (ArrayObject *)args[2];
u4debugFlags = args[3];
ArrayObject *rlimits = (ArrayObject *)args[4];
//设置信号处理,待会儿要看看这个函数。
setSignalHandler();
pid =fork(); //fork子进程
if (pid== 0) {
//对子进程要根据传入的参数做一些处理,例如设置进程名,设置各种id(用户id,组id等)
}
......
}
~~~
最后看看setSignalHandler函数,它由Zygote在fork子进程前调用,代码如下所示:
**dalvik_system_Zygote.c**
~~~
static void setSignalHandler()
{
interr;
structsigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler;
err =sigaction (SIGCHLD, &sa, NULL);//设置信号处理函数,该信号是子进程死亡的信号
}
//我们直接看这个信号处理函数sigchldHandler
static void sigchldHandler(int s)
{
pid_tpid;
intstatus;
while((pid = waitpid(-1, &status, WNOHANG)) > 0) {
} else if (WIFSIGNALED(status)) {
}
}
//如果死去的子进程是SS,则Zygote把自己也干掉了,这样就做到了生死与共!
if(pid == gDvm.systemServerPid) {
kill(getpid(), SIGKILL);
}
}
~~~
OK,做为Zygote的嫡长子,SS确实具有非常高的地位,竟然到了与Zygote生死与共的地步!它为什么这么重要呢?我们现在就从forkSystemServer来分析SS究竟承担了怎样的工作使命。
关于源代码定位的问题,不少人当面对浩瀚的代码时,常常不知道具体函数是在哪个文件中定义的。这里,就Source insight的使用提几点建议:
- 1)加入工程的时候,不要把所有目录全部加进去,否则会导致解析速度异常缓慢。我们可以先加入framework目录,如以后另有需要时,再加入其他目录。
- 2)除了Sourceinsight的工具外,还需要有一个能搜索文件中特定字符串的工具,我用的是coolfind。forkSystemServer这个函数,就是通过它在源码中搜索到的,并且找到了实现文件dalvik_system_Zygote.c。在Linux下也有对应工具,但工作速度比coolfind缓慢。
- 3) 在Linux下,可通过wine(一个支持Linux平台安装Windows软件的工具)安装Source insight。
';