您的位置:首页 > 编程语言 > Go语言

子进程system_service创建后while一直判断子进程状态是否died,如果会则zygote也kill自己

2013-11-14 16:01 721 查看
基于: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐