android 子进程源码分析,Android 杀应用进程的代码分析

杀死应用进程的代码分析

之前在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值