Linux上跑服務(wù)器如果遇到程序崩潰是一件很苦惱的事情, 再碰到重現(xiàn)很難的BUG, 估計(jì)只能通過(guò)傳統(tǒng)的排查方法進(jìn)行.
在編寫本文前, 筆者使用過(guò)諸如libunwind等庫(kù)進(jìn)行錯(cuò)誤時(shí)堆棧打印, 但是其本身由于需要引用第三方庫(kù), 使用還是稍微麻煩.
經(jīng)過(guò)Google后, 居然找到一篇好文, 其通過(guò)捕獲SIGSEGV信號(hào), 并迫使程序進(jìn)入gdb調(diào)試階段, 利用gdb強(qiáng)大的調(diào)試功能可以進(jìn)行各種錯(cuò)誤跟蹤, 此法已與Windows下程序崩潰后彈出VC調(diào)試幾乎接近.
我在此文基礎(chǔ)上, 擴(kuò)展了其通用性及便利性
1. 使用gdb的 -ex參數(shù), 在掛接程序后, 執(zhí)行bt指令打出程序堆棧
2. 將信息重定向到自定義的文件,在多進(jìn)程都需要進(jìn)行后臺(tái)輸出時(shí)帶來(lái)更大的靈活性, 同時(shí)也解決了gdb只能在前臺(tái)調(diào)試的問(wèn)題
代碼如下
#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);
}
在服務(wù)器開(kāi)啟時(shí),添加 signal(SIGSEGV, &dump ); 進(jìn)行信號(hào)處理掛接即可
引用: http://blog.csdn.net/kakaka2011/article/details/6597857 作者: kakaka2011