zoukankan      html  css  js  c++  java
  • Linux下利用backtrace追踪函数调用堆栈以及定位段错误【转】

    转自:https://www.linuxidc.com/Linux/2012-11/73470p2.htm

    通常情况系,程序发生段错误时系统会发送SIGSEGV信号给程序,缺省处理是退出函数。我们可以使用 signal(SIGSEGV, &your_function);函数来接管SIGSEGV信号的处理,程序在发生段错误后,自动调用我们准备好的函数,从而在那个函数里来获取当前函数调用栈。
    
    举例如下:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <execinfo.h>
    #include <signal.h>
    
    void dump(int signo)
    {
     void *buffer[30] = {0};
     size_t size;
     char **strings = NULL;
     size_t i = 0;
    
     size = backtrace(buffer, 30);
     fprintf(stdout, "Obtained %zd stack frames.nm
    ", size);
     strings = backtrace_symbols(buffer, size);
     if (strings == NULL)
     {
      perror("backtrace_symbols.");
      exit(EXIT_FAILURE);
     }
     
     for (i = 0; i < size; i++)
     {
      fprintf(stdout, "%s
    ", strings[i]);
     }
     free(strings);
     strings = NULL;
     exit(0);
    }
    
    void func_c()
    {
     *((volatile char *)0x0) = 0x9999;
    }
    
    void func_b()
    {
     func_c();
    }
    
    void func_a()
    {
     func_b();
    }
    
    int main(int argc, const char *argv[])
    {
     if (signal(SIGSEGV, dump) == SIG_ERR)
      perror("can't catch SIGSEGV");
     func_a();
     return 0;
    }
    
    编译程序:
    gcc -g -rdynamic test.c -o test; ./test
    输出如下:
    
    Obtained6stackframes.nm
    ./backstrace_debug(dump+0x45)[0x80487c9]
    [0x468400]
    ./backstrace_debug(func_b+0x8)[0x804888c]
    ./backstrace_debug(func_a+0x8)[0x8048896]
    ./backstrace_debug(main+0x33)[0x80488cb]
    /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x129113]
    
    接着:
    objdump -d test > test.s
    在test.s中搜索804888c如下:
    
    8048884 <func_b>:
    8048884: 55          push %ebp
    8048885: 89 e5      mov %esp, %ebp
    8048887: e8 eb ff ff ff      call 8048877 <func_c>
    804888c: 5d            pop %ebp
    804888d: c3            ret
    
    其中80488c时调用(call 8048877)C函数后的地址,虽然并没有直接定位到C函数,通过汇编代码, 基本可以推出是C函数出问题了(pop指令不会导致段错误的)。
    我们也可以通过addr2line来查看
    
    addr2line 0x804888c -e backstrace_debug -f 
    
    输出:
    
    func_b
    /home/astrol/c/backstrace_debug.c:57
  • 相关阅读:
    如何让实现整站变灰色调 (一般用于悼念活动)
    .net 泛型集合排序,查找
    Windows 2003服务器远程桌面配置
    .net 读取文件数据
    .net 验证工具类
    MS-SQL 基本语法大全
    SQL NVARCHAR和VARCHAR限制
    SQL SERVER DATETIME应用
    SQL事务在存储过程的应用
    移除button点击时的黑边
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/9235100.html
Copyright © 2011-2022 走看看