杀死应用进程的代码分析
之前在Android AMS启动Activity流程一文有写过进程启动的流程,这里不再赘述,这一章主要跟踪下杀进程的处理方式和流程。启动涉及到SING_QUIT3信号的处理,因为涉及trace的dump则单独在下一章说明。
用户空间杀进程
Process.java 官方的解释Tools for managing OS processes,之前在进程启动的时候AMS就是调用它的方法start然后实现和Zygote的Socket通信,请求fork应用进程的。
这里同样提供了杀进程的方法。
这里提供了三个方法,SIGNAL_KILL 这里定义为9,就是发9信号给对应进程。
killProcess(int pid)
==》sendSignal(pid, SIGNAL_KILL);
killProcessQuiet(int pid)
=》sendSignalQuiet(pid, SIGNAL_KILL);
killProcessGroup(int uid, int pid)
killProcess和killProcessQuiet
sendSignal是一个native方法,之前我们文档将Android启动流程的时候,Zygote启动阶段会调用AndroidRuntime::startReg注册系统Framework层的JNI方法。
AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_os_Process),
因此这个调用的是android_util_Process.cpp的android_os_Process_sendSignal方法
==》android_os_Process_sendSignal
void android_os_Process_sendSignal(JNIEnv* env, jobject clazz, jint pid, jint sig)
{
if (pid > 0) {
ALOGI("Sending signal. PID: %" PRId32 " SIG: %" PRId32, pid, sig);
kill(pid, sig);
}
}
上面提到的sendSignalQuiet(pid, SIGNAL_KILL);
void android_os_Process_sendSignalQuiet(JNIEnv* env, jobject clazz, jint pid, jint sig)
{
if (pid > 0) {
kill(pid, sig);
}
}
两个主要都是调用Kill函数
killProcessGroup
接着说killProcessGroup(int uid, int pid),它也是个native方法,对应JNI的实现是
jint android_os_Process_killProcessGroup(JNIEnv* env, jobject clazz, jint uid, jint pid)
{
return killProcessGroup(uid, pid, SIGKILL);
}
/system/core/libprocessgroup/processgroup.cpp
这里有killProcessGroup和killProcessGroupOnce两个入口函数,区别就是一个杀一次就行,另一个最大循环40次,直到指定进程组杀干净
int killProcessGroup(uid_t uid, int initialPid, int signal) {
return killProcessGroup(uid, initialPid, signal, 40 /*retries*/);
}
int killProcessGroupOnce(uid_t uid, int initialPid, int signal) {
return killProcessGroup(uid, initialPid, signal, 0 /*retries*/);
}
下面继续分析killProcessGroup的实现函数,以及杀进程在这个文件里最终的调用函数doKillProcessGroupOnce
killProcessGroup
这个函数的主要实现杀进程的作用是通过调用doKillProcessGroupOnce实现的。
这里我们上文提到两个函数传入的retries不同以实现多次下发杀进程的命令以达到杀死进程组的目的。
这里实现一个循环,通过retries值作为计数上限,循环调用doKillProcessGroupOnce。
static int killProcessGroup(uid_t uid, int initialPid, int signal, int retries) {
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
int retry = retries;
int processes;
//循环调用doKillProcessGroupOnce,直到processes小于等于0或者循环次数到达上限退出循环
while ((processes = doKillProcessGroupOnce(uid, initialPid, signal)) > 0) {
LOG(ERROR) << "Killed " << processes << " processes for processgroup " << initialPid;
if (retry > 0) {
std::this_thread::sleep_for(5ms);//线程休眠5ms
--retry;
} else {
break;
}
}
//processes 小于0
if (processes < 0) {
PLOG(ERROR) << "Error encountered killing process cgroup uid " << uid << " pid "
<< initialPid;
return -1;
}
//获取结束时间
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
//通过结束时间和起始时间计算杀进程一共耗掉的时间
auto ms = std::chrono::duration_cast(end - start).count();
// processes == 0说明进程已经被成功杀了
if (processes == 0) {
if (retries > 0) {
LOG(ERROR) << "Successfully killed process cgroup uid " << uid << " pid " << initialPid
<< " in " << static_cast(ms) << "ms";
}
//成功杀死进程,移除进程组相关目录
return removeProcessGroup(uid, initial