1. 程式人生 > >捕獲Linux段錯誤(Segment fault)並且列印錯誤堆疊

捕獲Linux段錯誤(Segment fault)並且列印錯誤堆疊

Linux上跑伺服器如果遇到程式崩潰是一件很苦惱的事情, 再碰到重現很難的BUG, 估計只能通過傳統的排查方法進行.

在編寫本文前, 筆者使用過諸如libunwind等庫進行錯誤時堆疊列印, 但是其本身由於需要引用第三方庫, 使用還是稍微麻煩.

經過Google後, 居然找到一篇好文, 其通過捕獲SIGSEGV訊號, 並迫使程式進入gdb除錯階段, 利用gdb強大的除錯功能可以進行各種錯誤跟蹤, 此法已與Windows下程式崩潰後彈出VC除錯幾乎接近.

我在此文基礎上, 擴充套件了其通用性及便利性

1. 使用gdb的 -ex引數, 在掛接程式後, 執行bt指令打出程式堆疊

2. 將資訊重定向到自定義的檔案,在多程序都需要進行後臺輸出時帶來更大的靈活性, 同時也解決了gdb只能在前臺除錯的問題

程式碼如下

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>

void dump(int signo)
{
        char buf[1024];
        char cmd[1024];
        FILE *fh;

        snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid());
        if(!(fh = fopen(buf, "r"
))) exit(0); if(!fgets(buf, sizeof(buf), fh)) exit(0); fclose(fh); if(buf[strlen(buf) - 1] == '/n') buf[strlen(buf) - 1] = '/0'; snprintf(cmd, sizeof(cmd), "gdb %s %d -ex=bt > ./a.txt", buf, getpid()); system(cmd); exit(0); }

在伺服器開啟時,新增 signal(SIGSEGV, &dump ); 進行訊號處理掛接即可