基于:http://blog.csdn.net/jianguo_liao19840726/article/details/16116859
我们进入到pid = Zygote.forkSystemServer(
native public static int forkSystemServer(int uid, int gid,
int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities);
来看看这个native方法的注释:
/**
* Special method to start the system server process. In addition to the
* common actions performed in forkAndSpecialize, the pid of the child
* process is recorded such that the death of the child process will cause
* zygote to exit.
这个注释很好解释,特别是the child process will cause zygote to exit ,就是由zygote fork 出的system_service进程如果死了,则 zygote进程也退出,我们还是进入其cpp中的方法来看一下吧,在dalvik.system.Zygote.c中,代码如下:
/* native public static int forkSystemServer(int uid, int gid,
* int[] gids, int debugFlags, long permittedCapabilities,
* long effectiveCapabilities);
*/
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
pid = forkAndSpecializeCommon(args, true);
/* The zygote process checks whether the child process has died or not. */
if (pid > 0) {
int status;
LOGI("System server process %d has been created", pid);
gDvm.systemServerPid = pid;
/* There is a slight window that the system server process has crashed
* but it went unnoticed because we haven't published its pid yet. So
* we recheck here just to make sure that all is well.
*/
if (waitpid(pid, &status, WNOHANG) == pid) {
LOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
}
RETURN_INT(pid);
}
const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
{ "fork", "()I",
Dalvik_dalvik_system_Zygote_fork },
{ "forkAndSpecialize", "(II[II[[I)I",
Dalvik_dalvik_system_Zygote_forkAndSpecialize },
{ "forkSystemServer", "(II[II[[IJJ)I",
Dalvik_dalvik_system_Zygote_forkSystemServer },
{ NULL, NULL, NULL },
};
从上面我们找到forkSystemServer对应的方法是Dalvik_dalvik_system_Zygote_forkSystemServer根据如下:
{ "forkSystemServer", "(II[II[[IJJ)I",
Dalvik_dalvik_system_Zygote_forkSystemServer }
上面贴出了Dalvik_dalvik_system_Zygote_forkAndSpecialize方法,其中涉及到
1、pid = forkAndSpecializeCommon(args, true); 主要用来fork 子进程system_service
2、waitpid(pid, &status, WNOHANG) == pid 检查,如果子进程died则 Restarting Zygote!
if (waitpid(pid, &status, WNOHANG) == pid) {
LOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
我们进入pid = forkAndSpecializeCommon(args, true);
static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{
setSignalHandler();
dvmDumpLoaderStats("zygote");
pid = fork();
if (pid == 0) {
Thread* thread = dvmThreadSelf();
thread->systemTid = dvmGetSysThreadId();
unsetSignalHandler();
} else if (pid > 0) {
/* the parent process */
}
return pid;
}
从上面我们看到了fork,但是我们也看到了,如果子进程died则会进入设置的信号处理函数
/*
* configure sigchld handler for the zygote process
* This is configured very late, because earlier in the dalvik lifecycle
* we can fork() and exec() for the verifier/optimizer, and we
* want to waitpid() for those rather than have them be harvested immediately.
*
* This ends up being called repeatedly before each fork(), but there's
* no real harm in that.
*/
static void setSignalHandler()
{
int err;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler;
err = sigaction (SIGCHLD, &sa, NULL);
if (err < 0) {
LOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
进入信号处理函数
/*
* This signal handler is for zygote mode, since the zygote
* must reap its children
*/
static void sigchldHandler(int s)
{
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/* Log process-death status that we care about. In general it is not
safe to call LOG(...) from a signal handler because of possible
reentrancy. However, we know a priori that the current implementation
of LOG() is safe to call from a SIGCHLD handler in the zygote process.
If the LOG() implementation changes its locking strategy or its use
of syscalls within the lazy-init critical section, its use here may
become unsafe. */
/*
* If the just-crashed process is the system_server, bring down zygote
* so that it is restarted by init and system server will be restarted
* from there.
*/
if (pid == gDvm.systemServerPid) {
LOG(LOG_INFO, ZYGOTE_LOG_TAG,
"Exit zygote because system server (%d) has terminated\n",
(int) pid);
kill(getpid(), SIGKILL);
}
}
}
信号处理函数可以看出一直在while,一直在查看子进程状态,如果子进程一旦died,则kill掉zygote