原文連接:http://www.cguru.net/?p=32
在編寫Java程序時,Exception類的printStacktrace()可以打印異常堆棧,這個小工具極大的提高了調試效率;雖然不是一個好習慣,卻很實用。習慣了Java編程,很希望 C/C++里也有這樣的小工具可以幫助調試程序.
在編寫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 ~]$
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
./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: 應用程序二進制接口)