分享

在Linux中打印函数调用堆栈

 昵称32814254 2017-02-08
        在编写Java程序时,Exception类的printStacktrace()可以打印异常堆栈,这个小工具极大的提高了调试效率;虽然不是一个好习惯,却很实用。习惯了Java编程,很希望 C/C++里也有这样的小工具可以帮助调试程序.
经过几天查找,发现其实每个系统都提供了打印调用堆栈的函数;这些函数是系统相关,这里仅以Linux下的函数作说明.
Linux中共提供了三个函数用于打印调用堆栈:

1
2
5
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);

 示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
  
void myfunc3(void)
{
    int j, nptrs;
    #define SIZE 100
    void *buffer[100];
    char **strings;
  
    nptrs = backtrace(buffer, SIZE);
    printf("backtrace() returned %d addresses\n", nptrs);
  
    backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO);
}
  
void myfunc(void)
{
    myfunc3();
}
  
int main(int argc, char *argv[])
{
    myfunc();
    return 0;
}

 程序运行结果:

[dma@bp860-10 ~]$ g++ -rdynamic t.cpp -o t  #这里的参数 -rdynamic 是必须
[dma@bp860-10 ~]$ ./t
backtrace() returned 5 addresses
./t(_Z7myfunc3v+0x1c)[0x4008c4]
./t(_Z6myfuncv+0x9)[0x4008f9]
./t(main+0x14)[0x400910]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3f37c1c40b]
./t(__gxx_personality_v0+0x3a)[0x40081a]
[dma@bp860-10 ~]$
 
虽然现在的程序可以输出函数调用的堆栈,但是函数多了一些前缀,比如:./t(_Z7myfunc3v+0x1c);这个问题可以通过c++fileter这个工具来解决:
[dma@bp860-10 ~]$ ./t | c++filt
./t(myfunc3()+0x1c)[0x4008c4]
./t(myfunc()+0x9)[0x4008f9]
./t(main+0x14)[0x400910]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3f37c1c40b]
./t(__gxx_personality_v0+0x3a)[0x40081a]
backtrace() returned 5 addresses

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多