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
  • 相关阅读:
    2018-4-17-软件设计-白话依赖注入
    2018-2-13-wpf-PreviewTextInput-在鼠标输入获得-_u0003
    2018-5-23-为何-987654321_123456789-的值是-8.0000000729
    寄存器位写操作
    Linux多IP配置
    Kconfig和Makefile
    linux设置网卡速率
    Winmanager,NERDTree和MiniBufExplorer
    SuperTab
    ping
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/9235100.html
Copyright © 2011-2022 走看看