作者:非台
背景
Android的ANR频次(Application Not Responding)一直是Android用户体验的重要指标,然而在Android 6.0+的设备上,由于设备anr目录权限的收敛,已经不能通过扫描/data/anr/traces.txt文件来获取ANR文件了,因此今天我们来简单聊聊获取ANR的另一种方式,Android环境下,信号SIGQUIT(3)拦截。
信号量处理
关于信号SIGQUIT的拦截,我们需要了解信号量处理的部分相关函数,kill、signal、sigaction、sigwait、pthread_sigmask等系统信号量处理相关函数是阅读本文的必备知识,因此在这一章节简单介绍下,更多系统函数知识,请阅读《UNIX环境高级编程》。
kill [1]
头文件:#include<signal.h>
定义函数:int kill(pid_t pid,int signo)
函数说明:kill函数可以对进程发送signal,Android AMS在发生ANR的是其实是通过Process.sendSignal(pid,signal)来通信的,Process.sendSignal方法在JNI层,其实调用的是kill
想详细了解ANR的同学可以看
- AppErrors.java:http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/AppErrors.java
- android_util_Process.cpp:http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/jni/android_util_Process.cpp
signal [2]
头文件:#include<signal.h>
定义函数:sig_t signal(int signum,sig_t handler);
函数说明:signal()用于确定以后当信号sig出现时的处理方法。如果handler的值是SIG_DFL,那么就采用实现定义的缺省行为;如果handler的值是SIG_IGN,那么就忽略该信号;否则,调用handler所指向的函数(参数为信号类型)。有效的信号包括:
SIGABRT |
异常终止,如调用abort()。 |
SIGFPE |
算术运算出错,如除数为0或溢出。 |
SIGILL |
非法函数映象,如非法指令。 |
SIGINT |
交互式信号,如中断。 |
SIGSEGV |
非法访问存储器,如访问不存在的内存单元。 |
SIGTERM |
发送给本程序的终止请求信号。 |
signal()返回信号sig原来的handler;如果出错,则返回SIG_ERR。当随后出现信号sig时,就中断正在执行的操作,转而执行信号处理函数(*handler)(sig)。如果从信号处理程序中返回,则从中断的位置继续执行。
sigaction [3]
头文件:#include<signal.h>
定义函数:int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact)