Android 信号处理面面观之trace 文件含义
http://blog.csdn.net/rambo2188/article/details/7017241
一. TRACE 文件的产生
Trace文件是 android davik 虚拟机在收到异常终止信号 (SIGQUIT)时产生的。 最经常的触发条件是 android应用中产生了 FC (force close)。由于是该文件的产生是在 DVM里,所以只有运行 dvm实例的进程(如普通的java应用,java服务等)才会产生该文件,android 本地应用 (native app,指 运行在 android lib层,用c/c++编写的linux应用、库、服务等)在收到 SIGQUIT时是不会产生 trace文件的。
如上文Android 信号处理面面观 之 信号定义、行为和来源所述,我们可以在终端通过adb发送SIGQUIT给应用来生成trace文件。
二. TRACE文件的实现
相关实现在以下几个文件中:
dalvik/vm/init.h [.c]
davik/vm/SignalCatcher.h[.c]
dalvik/vm/Thread.h[.c]
Android ICS 实现文件后缀是 .cpp。
实现过程分以下几步:
Step #1: DVM初始化时,设置信号屏蔽字,屏蔽要特殊处理的信号(SIGQUIT, SIGUSR1, SIGUSR2)。由于信号处理方式是进程范围起作用的, 这意味着该进程里所有的线程都将屏蔽该信号。 实现代码在init.c中如下:
[plain] view plaincopyprint?
int dvmStartup(int argc, const char* const argv[], bool ignoreUnrecognized,
JNIEnv* pEnv)
{
...
/* configure signal handling */
if (!gDvm.reduceSignals)
blockSignals();
...
}
blockSignals()的实现很简答,它是通过 sigprocmask() 函数调用实现的,代码在init.c如下:
[plain] view plaincopyprint?
/*
* Configure signals. We need to block SIGQUIT so that the signal only
* reaches the dump-stack-trace thread.
*
* This can be disabled with the "-Xrs" flag.
*/
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);
}
Step #2: DVM 生成单独的信号处理线程,用来对三个信号做特殊处理 (init.c):
[plain] view plaincopyprint?
/*
* Do non-zygote-mode initialization. This is done during VM init for
* standard startup, or after a "zygote fork" when creating a new process.
*/
bool dvmInitAfterZygote(void)
{
...
/* start signal catcher thread that dumps stacks on SIGQUIT */