backtrace() 段错误定位

段错误定位

原因是昨天遇到一个BUG,复现概率很小,一直复现了一下午,后来google发现可以用execinfo.h里的backtrace函数及信号处理机制, 来让程序在发生段错误时自动打印调用堆栈。最后终于复现出来了两次,用这个函数也定位到了出错位置,是多线程下的一个同步问题。

之前遇到的BUG基本都是可复现的,用简单的打印很快就能定位到BUG位置。对于这种不可复现的BUG在开发测试的时候最好能一直带着backtrace函数,以最快的速度定位BUG。

#include <execinfo.h>
#define BACKTRACE_SIZE 256
void segv_handler(int sig)
{
    void *func[BACKTRACE_SIZE];
    int size;
    size = backtrace(func, BACKTRACE_SIZE);
    backtrace_symbols_fd(func, size, STDERR_FILENO);
    exit(1);
}

int main(void)
{
    int *p = NULL;
    signal(SIGSEGV, segv_handler);
    *p = 0xdeadbeef; //---------------------Line 29
    return 0;
}

程序开始的时候注册一下SIGSEGV信号的回调,然后编译的时候带上-g。程序运行出错的时候会以汇编的形似打印调用栈。形式一般是这样:

./auto[0x400654]
/lib64/libc.so.6(+0x35250)[0x7fbbe4283250]
./auto[0x400543] //----------------出错地址
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fbbe426fb35]
./auto[0x40057e]

前边两行是SIGSEGV信号被触发的回调,第三行是段错误的位置。addr2line -e auto 0x400543可以打印出这个地址对应的代码位置。或者也可以用objdump -d xxx打印出来汇编然后去搜索这个地址。

PS:还有两个内存调试工具 valgrind检查内存泄漏; electric fence检查非法地址访问。
参考:https://www.cnblogs.com/lchzd8/p/15845824.html

posted @ 2024-07-09 09:32  hellozhangjz  阅读(33)  评论(0编辑  收藏  举报