我們知道,
gdb的
backtrace
命令可以檢視堆疊資訊。但很多時候,
gdbgdb
,即使有,也不太可能讓我們直接在上面除錯。如果能讓程式自己輸出呼叫棧,那是最好不過了。本文介紹和呼叫椎棧相關的幾個函式。
以上內容源自這幾個函式的
man手冊。
先簡單介紹一下這幾個函式的功能: l
backtrace
:獲取當前的呼叫棧資訊,結果儲存在
buffer
中,返回值為棧的深度,引數
size
限制棧的最大深度,即最大取
size
步的棧資訊。 l
backtrace_symbols
:把backtrace
獲取的棧資訊轉化為字串,以字元指標陣列的形式返回,引數
size
限定轉換的深度,一般用
backtrace
呼叫的返回值。 l
backtrace_symbols_fd
:它的功能和
backtrace_symbols
差不多,只不過它不把轉換結果返回給呼叫方,而是寫入
fd指定的檔案描述符。
man手冊裡,給出了乙個簡單的例項,我們看一下:
#include
#include
#include
#include
void
myfunc3(void)
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings); }
static
void
/* "static" means don't export the symbol... */
myfunc2(void)
void
myfunc(int ncalls)
intmain(int argc,char *argv)
myfunc(atoi(argv[1]));
exit(exit_success); }
編譯:# cc prog.c -o prog
執行:
# ./prog 0
backtrace() returned 6 addresses
./prog() [0x80485a3]
./prog() [0x8048630]
./prog() [0x8048653]
./prog() [0x80486a7]
這樣,是輸出了呼叫棧,不過只是以十六進製制輸出函式位址而已,可讀性很差。仔細看下
man手冊,原來很簡單,編譯時加上個引數:
重新編譯:
# cc -rdynamic prog.c -o prog
通過gcc
手冊,我們可以也解下引數的說明
:-rdynamic
pass the flag -export-dynamic to the elf linker, on targets that support it. this instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. this option is needed for some uses of "dlopen" or to allow obtaining backtraces from within a program.
再執行:
# ./prog 0
backtrace() returned 6 addresses
./prog(myfunc3+0x1f) [0x8048763]
./prog() [0x80487f0]
./prog(myfunc+0x21) [0x8048813]
./prog(main+0x52) [0x8048867]
/lib/libc.so.6(__libc_start_main+0xe6) [0xaf9cc6]
./prog() [0x80486b1]
這回,可以看到函式名了。是不是很酷呢?把它封裝到你的除錯**中吧。
linux環境在程式中列印呼叫棧的方法
使用除錯工具進行bug處理時非常有用,在閱讀和分析源 時也非常有用,以下 就說明了如何在自己的程式中列印呼叫堆疊 include include include include void print trace void void mytrace void for j 0 j nptrs j pri...
在Linux應用程式中列印函式呼叫棧
在linux中列印函式呼叫棧 要求在linux系統的應用程式中寫乙個函式print stackframe 用於獲取當前位置的函式呼叫棧資訊 方法execinfo.h庫下的函式backtrace可以得到當前執行緒的函式呼叫棧指標和呼叫棧深度,backtrace symbols可以將呼叫棧指標轉化為字串...
linux 列印引數呼叫棧和入參資訊
方法1 include include include obtain a backtrace and print it to stdout.void print trace void int main g stack.c g o stack rdynamic 方法2 include include ...