处理程序中的段错误

void dump_stack(FILE *log)
{
    void *bufs[100];
    int n = backtrace(bufs, 100);
    char **infos = backtrace_symbols(bufs, n);

    if (!infos)
    {
        exit(1);
    }

    fprintf(log, "==================\n");
    fprintf(log, "Frame info:\n");
    char cmd[512];
    char tmp[512];
    sprintf(tmp, "addr2line -ifC -e %s", appName);
    int len = snprintf(cmd, sizeof(cmd),
                       tmp);
    char *p = cmd + len;
    size_t s = sizeof(cmd) - len;

    for (int i = 0; i < n; ++i)
    {
        fprintf(log, "%s\n", infos[i]);

        if (s > 0)
        {
            len = snprintf(p, s, " %p", bufs[i]);
            p += len;
            s -= len;
        }
    }

    fprintf(log, "src info:\n");
    FILE *fp;
    char buf[128];

    if ((fp = popen(cmd, "r")))
    {
        while (fgets(buf, sizeof(buf), fp))
        {
            fprintf(log, "%s", buf);
        }

        pclose(fp);
    }

    fprintf(log, "==================\n");
    free(infos);
    // same as:
    //backtrace_symbols_fd(bufs, n, STDOUT_FILENO);
}

void segv_handle(int s)
{
    system("rm /opt/yl/wf.cfg");
    dump_stack(stdout);
    exit(127 + s);
}

main.cpp
signal(SIGSEGV, segv_handle);

这段代码是用于处理程序中的段错误(Segmentation Fault)的。当程序发生段错误时,它会执行segv_handle函数。

  1. dump_stack函数

    • 该函数首先使用backtrace函数来获取当前线程的堆栈信息,并将其存储在bufs数组中。
    • 接下来,它使用backtrace_symbols函数将这些地址转化为更有意义的函数名、文件名和行号信息,并将这些信息存储在infos数组中。
    • 如果无法获取堆栈信息,程序将退出。
    • 然后,它将这些堆栈信息写入到指定的日志文件(通过FILE *log参数传递)。
    • 之后,它使用addr2line工具(通过系统调用来执行)来获取源代码位置信息,并将这些信息也写入到日志中。
    • 最后,它释放了infos数组。
  2. segv_handle函数

    • 当程序发生段错误时,会调用此函数。
    • 首先,它会删除一个名为/opt/ylswt/swt.cfg的文件。
    • 然后,它调用dump_stack函数来记录当前的堆栈信息到标准输出(通常是终端或控制台)。
    • 最后,它以特定的退出码退出程序。这个退出码是127加上段错误的信号码。

总体来说,这段代码的目的是在发生段错误时,提供详细的堆栈信息和源代码位置信息,以便于调试和解决问题。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值