利用backtrace和ucontex定位segment错误

本文介绍了如何在C程序中处理segmentfault错误,通过设置SIGSEGV信号处理函数,结合backtrace和backtrace_symbols获取函数调用栈信息。同时,文章还展示了如何使用ucontext_t结构来获取引起异常的指令地址,帮助开发者定位问题。
摘要由CSDN通过智能技术生成

         C程序运行时,经常会碰到”segmentfault”错误。这是由于程序中非法访问内存导致的。当操作系统的内存保护机制发现进程访问了非法内存的时候会向此进程发送一个SIGSEGV信号,导致进程直接退出,并在shell中提示segment fault。

 

         因此,可以通过设置SIGSEGV信号处理函数,在处理函数中调用backtrace系列函数得到异常时的函数调用栈信息。

 

一:backtrace

         backtrace系列函数的原型如下:

#include <execinfo.h>

int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

         backtrace函数通过指针数组buffer返回调用程序的回溯信息,也就是所谓的函数调用栈。buffer数组中的元素是void*类型,也就是栈中保存的返回地址。

         size参数指定buffer中可以保存的地址的最大个数。如果实际的回溯信息大于size,则只返回最近的size个地址。

         backtrace函数返回buffer中保存的地址个数,返回值不会大于size。如果返回值小于size,则说明所有的回溯信息都已经返回了,如果等于size,则有可能被截断了。

 

         backtrace函数在buffer数组中返回的都是一些虚拟地址,不适于分析。backtrace_symbols函数可以将backtrace返回的buffer中的地址,根据符号表中的信息,转换为字符串(函数名+偏移地址)。size参数指明了buffer中的地址个数。

         backtrace_symbols返回字符串数组的首地址,该字符串是在backtrace_symbols中通过malloc分配的,因此,调用者必须使用free释放内存。如果发生了错误,则backtrace_symbols返回NULL。

 

         backtrace_symbols_fd类似于backtrace_symbols,只不过它是把字符串信息写到文件描述符fd所表示的文件中。backtrace_symbols_fd不会调用malloc函数。

 

         注意,编译器的优化策略,可能导致得到的回溯信息不准确。而且,对于GUN编译器而言,必须使用-rdynamic链接选项,才能正确解析出符号名。

 

二:示例

#include <signal.h>
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>

#define BTSIZE 100

static void sig_handler(int sig, siginfo_t *info, void *secret)
{
    ucontext_t *uc = (ucontext_t*) secret;

    void *buffer[BTSIZE];
    char **strings;
        int nptrs = 0;

    printf("in sig_handler\n");
    pri
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值