战魂小筑

讨论群:309800774 知乎关注:http://zhihu.com/people/sunicdavy 开源项目:https://github.com/davyxu

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  248 随笔 :: 0 文章 :: 503 评论 :: 0 Trackbacks

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 ); 进行信号处理挂接即可

 

 

引用: http://blog.csdn.net/kakaka2011/article/details/6597857  作者: kakaka2011

posted on 2012-12-29 17:53 战魂小筑 阅读(6593) 评论(3)  编辑 收藏 引用 所属分类: 程序调试技术网络 服务器技术C++/ 编程语言

评论

# re: 捕获Linux段错误(Segment fault)并且打印错误堆栈 2013-01-04 12:37 peakflys
其实这种情况实现的方法有很多,例如backtrace等等,但是这种情况在服务器上试问有什么意义?通过这种方法打出来的东西远远没有OS dump出的程序core文件包含的信息多……
PS,这种情况在C/S架构的C端才有相应的应用价值,通过网络 把远端客户端dump出的信息传送过来,便于客户端查错而已。  回复  更多评论
  

# re: 捕获Linux段错误(Segment fault)并且打印错误堆栈 2013-04-15 13:19 Adrian
这个好,备份在你这里,以后用得上。  回复  更多评论
  

# re: 捕获Linux段错误(Segment fault)并且打印错误堆栈 2013-10-11 16:47 zozo
刚开始开到文章的时候很欣喜,一直有这方面的困惑,windows下有dump, linux下怎么办,难道只能通过日志?楼主的文章就是我想要的。

又突然想起来linux可以通过命令,在进程崩溃的时候,让系统来生成dump core文件。也就是前面 peakflys所说的 ,没必要自己去生成dump了。

ps. google breakpad也是,对客户端有效,对服务端没必要。  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理