android signal 处理总结

来源:互联网 发布:mysql官方 编辑:程序博客网 时间:2024/05/01 21:15

转载自:http://www.2cto.com/kf/201311/259749.html

 

在Android 开发中遇到一些signal 的情况,简要总结如下:

 
1)Zygote 监控 子进程的退出情况
 
jellybean/dalvik/vm/native/dalvik_system_Zygote.cpp#151
    151     sa.sa_handler = sigchldHandler;
 
    153     err = sigaction (SIGCHLD, &sa, NULL);
 
当进程结束的时候,log 中有类似下面的消息,这就是 Zygote打印出来,它会报告子进程被什么 signal 终结的
 
D Zygote  : Process 749 terminated by signal (11)
 
2)DVM 生成单独的信号处理线程,用来对三个信号做特殊处理:
 
每个进程包含多个线程,当进程受到 signal 的时候,可能被其中任何一个线程处理
 
一个应用运行在虚拟机上dvm上一个应用也是一个dvm 进程,dvm 专门创建了一个信号处理线程来处理这3个信号,其他的线程都要block对这三个信号的处理。
 
这三个信号是 SIGQUIT, SIGUSR1, SIGUSR2, 看下面代码,后面两个信号 vm 内部要使用
 
dalvik/vm/Init.cpp
 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static void blockSignals()    
{    
    sigset_t mask;    
    int cc;    
      
    sigemptyset(&mask);    
    sigaddset(&mask, SIGQUIT);    
    sigaddset(&mask, SIGUSR1);      // used to initiate heap dump    
#if defined(WITH_JIT) && defined(WITH_JIT_TUNING)    
    sigaddset(&mask, SIGUSR2);      // used to investigate JIT internals    
#endif    
    //sigaddset(&mask, SIGPIPE);    
    cc = sigprocmask(SIG_BLOCK, &mask, NULL);    
    assert(cc == 0);    
}

 

 
为何处理 quit
 
Android 应用在收到异常终止信号(SIGQUIT)时,没有遵循传统 UNIX信号模型的默认行为 (终止 + core )。而是打印出trace 文件来,以利于记录应用异常终止的原因。 
 
Trace文件是 android davik 虚拟机在收到异常终止信号 (SIGQUIT)时产生的。 最经常的触发条件是 android应用中产生了 FC (force close)。由于是该文件的产生是在 DVM里,所以只有运行 dvm实例的进程(如普通的java应用,java服务等)才会产生该文件,android 本地应用 (native app,指 运行在 android lib层,用c/c++编写的linux应用、库、服务等)在收到 SIGQUIT时是不会产生 trace文件的。
参考
 
http://blog.csdn.net/rambo2188/article/details/7017241
 
 
3) 其他基于 bionic 的应用,都被  Android 动了手脚
 
android的实现是在 main 运行之前 先运行 debugger_init 方法,以实现拦截系统异常的几个singal:SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV和SIGPIPE, 代码位于: bionic/linker/debugger.c, 把 debugger_init 注入 是通过在 linker 中做手脚 (bionic/linker/linker.c#2255)
 
而后当程序收到那几个信号后,不是安装 linux  缺省的处理方法,而是运行 debugger_init 中设定的信号处理方法,此方法就是和 debuggerd (守护进程)通信,通过socket告诉其  tid ,
 
而后  debuggerd 通过调用
 
tid_attach_status= ptrace(PTRACE_ATTACH, tid, 0, 0);
 
这里,debuggerd就挂上ptrace了,attach到出问题的线程,debuggerd进程就是被调试进程的父进程了,这样debuggerd就可以控制tid线程了,最终生成  tomestone的信息
0 0
原创粉丝点击