android signal 6,android signal 处理总结

督飞羽
2023-12-01

在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的信息

 类似资料: