應用程式除錯 signal和backtrace

2021-08-18 12:04:31 字數 3329 閱讀 8862

優秀部落格:

一般察看函式執行時堆疊的方法是使用gdb(bt命令)除錯工具。但是,有些時候為了分析程式的bug(主要針對長時間執行程式的分析),在程式出錯時列印出函式的呼叫堆疊是非常有用的。

作用:用於程式異常退出時尋找錯誤原因。

功能:回溯堆疊,簡單的說就是可以列出當前函式呼叫關係。

原理:

在glibc標頭檔案」execinfo.h」中宣告了三個函式用於獲取當前執行緒的函式呼叫堆疊。

/*

說明: 1. 該函式用於獲取當前執行緒的呼叫堆疊,獲取的資訊將會被存放在buffer中,它是乙個指標列表。

引數 size 用來指定buffer中可以儲存多少個void* 元素。函式返回值是實際獲取的指標個數,

最大不超過size大小。

2. 在buffer中的指標實際是從堆疊中獲取的返回位址,每乙個堆疊框架有乙個返回位址。

3. 某些編譯器的優化選項會對獲取正確的呼叫堆疊有干擾;

4. 內聯函式沒有堆疊框架;

5. 刪除框架指標也會導致無法正確解析堆疊內容。

*/int backtrace(void **buffer, int size)

/*

說明: 1. backtrace_symbols將從backtrace函式獲取的資訊轉化為乙個字串陣列。

2. 引數buffer應該是從backtrace函式獲取的指標陣列,size是該陣列中的元素個數(backtrace的返回值)。

3. 函式返回值是乙個指向字串陣列的指標,它的大小同buffer相同。每個字串包含了乙個相對於

buffer中對應元素的可列印資訊。它包括函式名、函式的偏移位址、實際的返回位址。

4. 目前,只有使用elf二進位制格式的程式才能獲取函式名稱和偏移位址。在其他系統,只有16進製制的返回位址能被

獲取。另外,你可能需要傳遞相應的符號給鏈結器,以能支援函式名功能。(比如,在使用gnu ld鏈結器的系統

中,器支援-rdynamic的話,建議將其加上!)

5. 該函式的返回值是通過malloc函式申請的空間,因此呼叫者必須使用free函式來釋放指標。

6. 如果不能為字串獲取足夠的空間函式的返回值將會為null。

*/char ** backtrace_symbols (void *const *buffer, int size)

/*

說明: 1. backtrace_symbols_fd與backtrace_symbols 函式具有相同的功能,不同的是它不會給呼叫者

返回字串陣列,而是將結果寫入檔案描述符為fd的檔案中,每個函式對應一行.它不需要呼叫malloc函式,

因此適用於有可能呼叫該函式會失敗的情況。

*/void backtrace_symbols_fd(void *const *buffer, int size, int fd)

如果是x86平台gcc編譯:

gcc -g -rdynamic backtrace.c -o backtrace如果是arm平台arm-linux-gcc交叉編譯,需要帶如下編譯引數:

-rdynamic

-funwind-tables

-ffunction-sections

否則可能backtrace返回值為0,得不到需要的資訊。

/* backtrace.c */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define backtrace_buf_size 50

void sig_children(int signal)

}void sigsegv_handler(int signal)

/* the call backtrace_symbols_fd(buffer, nptrs, stdout_fileno)

would produce similar output to the following: */

strings = backtrace_symbols(buffer, nptrs);

if (strings == null)

for (j = 0; j < nptrs; j++)

free(strings);

exit(-1);

}void main(int argc, char *argv)

1.通過objdump工具(注:只有加了編譯選項的,彙編結果才能有對應的c語言。)

x86:

objdump

arm:

arm-poky-linux-gnueabi-objdump

例如:

objdump -d backtrace > backtrace.s//沒有對應的c語句

objdump -s backtrace | less//可能有對應的c語句,取決於編譯時新增的編譯選項。

2.通過addr2line工具

ARM Linux應用程式除錯環境

建立arm linux應用程式除錯環境 gdb gdbserver insight環境的搭建 2.配置安裝gdb gdbser tar jxvf gdb 6.6.tar.bz2 cd x gdb configure target arm linux prefix usr local arm gdb ...

除錯多執行緒應用程式

對於多執行緒應用程式的除錯 各開發工具都有良好的支援,使用廣泛的為windows下vs及unix下的 ms對vs除錯多執行緒程式給出了詳細的幫助手冊,可以在msdn中搜尋 setthreadname 設定執行緒名稱 中找到相關頂級主題 除錯多執行緒應用程式 ms help 以下文字摘自msdn 執行...

使用gdb除錯應用程式

toc gdb是乙個由gnu開源組織發布的 unix linux作業系統下的 基於命令列的 功能強大的程式除錯工具。對於一名linux下工作的c 程式設計師,gdb是必不可少的工具 對於c c 程式,編譯的時候需要加上 g引數生成除錯資訊。如 gcc g hello.c o hello 啟動gdb後...