有关应用程序的信息:
- Linux-2.4.1内核
- 基于m68k的嵌入式应用程序
- 单进程多线程应用程序
我们有一个应用程序,其中我们使用segmentation_handler函数实现了SIGSEGV的连接。在这个分段处理程序中,我们创建一个文件,进行文件写入(如"获得的堆栈帧"),然后使用回溯和符号将所有堆栈跟踪写入同一个文件。
问题:我们得到了一个SIGSEGV(由于创建了日志文件而得到确认),但不幸的是,该文件是空的(0kb文件),其中没有任何信息。(即使是第一个纯字符串在文件中也不可用)。
我想了解在什么情况下会发生这样的事情,因为如果我们得到堆栈跟踪,我们可以解决崩溃,但我们没有它,而且得到它的机制也不起作用:(
void segmentation_handler(int signal_no) {
char buffer[512]; .............
InitLog();//Create a log file
printf("n*** segmentation fault occured ***n");
fflush(stdout);
memset(buffer, 0, 512);
size = backtrace (array, 50);
strings = backtrace_symbols (array, size);
sprintf(buffer, "Obtained %d stack frames.n", size);
Log(buffer);// Write the buffer into the file
for (n = 0; n < size; n++) {
sprintf(buffer, "%sn", strings[n]); Log(buffer);
}
CloseLog();
}
您的分段处理程序非常幼稚,包含多个错误。以下是一个简短的列表:
-
您正在调用fprintf()和其他多个异步信号不安全的函数。考虑一下,fprintf在内部使用锁来同步来自多个线程的对同一文件描述符的多个调用。如果您的分段错误在printf的中间,并且锁定被占用了,会怎么样?你会死锁在分割处理程序的中间。。。
-
您正在分配内存(调用backtrace_symbols),但如果分段错误是由于malloc arena损坏(很可能是分段冲突的原因)造成的,则分段处理程序内部会出现双重错误。
-
如果多个线程在同一时间内导致异常,则代码将多次打开文件并在日志上运行。
还有其他问题,但这些都是基础。。。
我的讲座中有一段关于如何编写正确的故障处理程序的视频,可在此处获得:http://free-electrons.com/pub/video/2008/ols/ols2008-gilad-ben-yossef-fault-handlers.ogg
-
删除分段处理程序。
-
允许程序转储核心(ulimit-c无限制或进程中的setrlimit)
-
看看你是否有一个核心文件。
-
使用工具链调试器离线执行回溯操作
您还可以编写一个专门的segfault程序,并测试这两种方法(即使用核心文件或在信号处理程序中进行验尸)。