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

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Segmentation fault段错误)通常是由于程序访问了无效的内存地址引起的。在 Linux 中,可以使用以下方法来查看段错误的原因: 1. 使用 gdb 调试器 使用 gdb 可以帮助我们定位代码中出现段错误的位置。首先,需要在编译时加上 `-g` 选项生成调试信息。然后,在运行程序时,使用 gdb 启动程序,并在出现段错误时停止程序。可以使用 `bt` 命令查看调用栈,找到出现段错误的位置。例如: ``` $ gcc -g -o myprogram myprogram.c $ gdb myprogram (gdb) run Starting program: /home/user/myprogram Program received signal SIGSEGV, Segmentation fault. 0x00005555555546d3 in main () (gdb) bt #0 0x00005555555546d3 in main () ``` 在上面的示例中,我们在 `main` 函数中出现了段错误。 2. 使用 valgrind 工具 valgrind 是一款用于检测内存泄漏和内存访问错误的工具。可以在 Linux 中使用以下命令来安装 valgrind: ``` $ sudo apt-get install valgrind ``` 然后,在运行程序时使用 valgrind 工具检测内存错误。例如: ``` $ valgrind ./myprogram ``` valgrind 会输出内存错误的详细信息,帮助我们定位问题。 3. 使用系统日志 当程序出现段错误时,Linux 系统会将错误信息写入系统日志。可以使用以下命令来查看系统日志: ``` $ dmesg | tail ``` 在输出中,可以找到与段错误相关的信息,例如内存地址和错误代码。 通过以上方法,我们可以定位并解决程序中出现的段错误

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值