在Linux中打印函數調用堆棧(一)


原文連接:http://www.cguru.net/?p=32

在編寫Java程序時,Exception類的printStacktrace()可以打印異常堆棧,這個小工具極大的提高了調試效率;雖然不是一個好習慣,卻很實用。習慣了Java編程,很希望 C/C++里也有這樣的小工具可以幫助調試程序.
經過幾天查找,發現其實每個系統都提供了打印調用堆棧的函數;這些函數是系統相關,這里僅以Linux下的函數作說明.
Linux中共提供了三個函數用於打印調用堆棧:
 
         
/*
* 函數說明: 取得當前函數的調用堆棧
* 參數:
*     buffer:用於存儲函數地址的數組
*     size:buffer數組的長度
* 返回值:
*      存儲到數組中的函數個數
*/
int backtrace(void **buffer, int size);

/*
*
* 函數說明:將一組函數地址轉換為字符串
* 參數: 
*      buffer: 經由backtrace得到的函數地址
*      size: buffer數組的長度
* 返回值: 
*       函數在系統中對應用字符串
*/
char **backtrace_symbols(void *const *buffer, int size);

/*
* 函數說明:將一組函數地址轉換為字符串
* 參數: 
*      buffer: 經由backtrace得到的函數地址
*      size: buffer數組的長度
*      fd: 輸出結果文件描述符
*/
void backtrace_symbols_fd(void *const *buffer, int size, int fd);
 
         

 示例程序:

#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
 
(未完,待續:C++ ABI: 應用程序二進制接口)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM