SIGSEGV崩溃,但无法收集回溯



有关应用程序的信息:

  • 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();
}

您的分段处理程序非常幼稚,包含多个错误。以下是一个简短的列表:

  1. 您正在调用fprintf()和其他多个异步信号不安全的函数。考虑一下,fprintf在内部使用锁来同步来自多个线程的对同一文件描述符的多个调用。如果您的分段错误在printf的中间,并且锁定被占用了,会怎么样?你会死锁在分割处理程序的中间。。。

  2. 您正在分配内存(调用backtrace_symbols),但如果分段错误是由于malloc arena损坏(很可能是分段冲突的原因)造成的,则分段处理程序内部会出现双重错误。

  3. 如果多个线程在同一时间内导致异常,则代码将多次打开文件并在日志上运行。

还有其他问题,但这些都是基础。。。

我的讲座中有一段关于如何编写正确的故障处理程序的视频,可在此处获得:http://free-electrons.com/pub/video/2008/ols/ols2008-gilad-ben-yossef-fault-handlers.ogg

  • 删除分段处理程序。

  • 允许程序转储核心(ulimit-c无限制或进程中的setrlimit)

  • 看看你是否有一个核心文件。

  • 使用工具链调试器离线执行回溯操作

您还可以编写一个专门的segfault程序,并测试这两种方法(即使用核心文件或在信号处理程序中进行验尸)。

最新更新