首页 > 系统服务 > 详细

linux应用程序调试----backtrace

时间:2020-12-11 22:37:29      阅读:33      评论:0      收藏:0      [点我收藏+]

打印堆栈是调试的常用方法,一般在系统异常时,我们可以将bai异常情况下的堆栈打印出来,这样十分方便错误查找。

先介绍下比较简单的backtrace方式,后面有机会可以尝试下core文件+gdb的方式。

 

backtrace打印堆栈方式

编译选项增加  -O0 -rdynamic -g -funwind-tables -ffunction-sections

CFLAGS ?= -mcpu=ck810 -static -mlittle-endian -Werror -O0 -rdynamic -g -funwind-tables -ffunction-sections

ASFLAGS += -O0

 

代码添加

#include <signal.h>       /* for signal */  
#include <execinfo.h>     /* for backtrace() */  

#define BACKTRACE_SIZE   32  
  
void dump(void)  
{  
    int j, nptrs;  
    void *buffer[BACKTRACE_SIZE];  
    char **strings;  

    printf("backtrace...\n");
    
    nptrs = backtrace(buffer, BACKTRACE_SIZE);  
      
    printf("backtrace() returned %d addresses\n", nptrs);  
  
    strings = backtrace_symbols(buffer, nptrs);  
    if (strings == NULL) {  
        perror("backtrace_symbols");  
        exit(EXIT_FAILURE);  
    }  
  
    for (j = 0; j < nptrs; j++)  
        printf("  [%02d] %s\n", j, strings[j]);  
  
    free(strings);  
}  



void signal_handler(int signo)  
{  
      
#if 0     
    char buff[64] = {0x00};  
          
    sprintf(buff,"cat /proc/%d/maps", getpid());  
          
    system((const char*) buff);  
#endif    
  
    printf("\n=========>>>catch signal %d <<<=========\n", signo);  
      
    printf("Dump stack start...\n");  
    dump();  
    printf("Dump stack end...\n");  

    //exit(-1);
    signal(signo, SIG_DFL); /* 恢复信号默认处理 */  
    raise(signo);           /* 重新发送信号 */  

    printf("app exit\n");  
}  

int main(void)
{
  signal(SIGABRT, signal_handler);
  signal(SIGBUS, signal_handler); 
  signal(SIGSEGV, signal_handler); 

}

  

执行结果:

=========>>>catch signal 11 <<<=========
Dump stack start...
backtrace...
backtrace() returned 7 addresses
[00] ./app-demo() [0xbf6e]              // 最后一条指令
[01] ./app-demo() [0xc086]              // 倒数第2调指令
[02] [0x2aac6000]
[03] /lib/libc.so.6(memcpy+0x30) [0x2ab516a0]
[04] ./app-demo() [0xbb62]              // 出问题的地方
[05] ./app-demo() [0x9e92]
[06] /lib/libpthread.so.0(+0x61d0) [0x2aacd1d0]
Dump stack end...
app exit
Segmentation fault

 

文件分析:

再虚拟机上使用GNU工具集中的addr2line工具获取源码位置

# addr2line -e app/app-demo 0xbc62 

# /home/cql/smb/fuxi_h/demo-linux-wjc-20201211/app/main.c:538

 

 

附录:

         SIGHUP 1 A 终端挂起或者控制进程终止 
         SIGINT 2 A 键盘中断(如break键被按下) 正常终止
         SIGQUIT 3 C 键盘的退出键被按下 
         SIGILL 4 C 非法指令 
        SIGABRT 6 C 由abort(3)发出的退出指令,异常终止 
         SIGIO 23,29,22 A 某I/O操作现在可以进行了(4.2 BSD)
         SIGKILL 9 AEF 杀死进程的终极方法
        SIGSEGV 11 C 无效的内存引用 
        SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道 
         SIGALRM 14 A 由alarm(2)发出的信号 
        SIGTERM 15 A 终止信号 
         SIGUSR1 30,10,16 A 用户自定义信号1 给用户做进程间通信,不像其他的处理方法被绑定了
         SIGUSR2 31,12,17 A 用户自定义信号2 
         SIGCHLD 20,17,18 B 子进程结束信号 
         SIGCONT 19,18,25 进程继续(曾被停止的进程) 
         SIGSTOP 17,19,23 DEF 终止进程 
         SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键 
         SIGTTIN 21,21,26 D 后台进程企图从控制终端读 
         SIGTTOU 22,22,27 D 后台进程企图从控制终端写       

 

linux应用程序调试----backtrace

原文:https://www.cnblogs.com/mic-chen/p/14121778.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!