【轉(zhuǎn)】用backtrace()調(diào)試coredump問題

嵌入式開發(fā)環(huán)境下,用gdb調(diào)試coredump的問題可能是件麻煩事。用 backtrace() 和 backtrace_symbols() 可以獲取當(dāng)前線程的調(diào)用棧的信息,可以快捷定位coredump的位置。

1. 打印調(diào)用棧

1.1 backtrace()

backtrace() 向數(shù)組buffer寫入當(dāng)前調(diào)用棧中每個(gè)棧幀的返回地址。100是buffer的大小,返回值nptrs是返回棧幀的個(gè)數(shù)。如果buffer不夠大,則返回最近的幀。

void *buffer[100];
int nptrs = backtrace (buffer, 100);

1.2 backtrace_symbols()

backtrace_symbols() 將 backtrace() 返回的地址數(shù)組,轉(zhuǎn)換成字符串形式的符號(hào)信息。返回值strings是char*類型的數(shù)組,由backtrace_symbols()調(diào)用malloc()分配,調(diào)用者需要釋放strings(但不需要釋放數(shù)組中的字符串)。

char** strings = backtrace_symbols (buffer, nptrs);
for (int i = 0; i < nptrs; i++)
    printf ("%s\n", strings[i]);

與backtrace_symbols()類似的,還有backtrace_symbols_fd()。不同的是,它將符號(hào)信息的字符串寫入fd指定的文件中,每個(gè)字符串一行。

2. 捕捉信號(hào)

可以捕捉常見的錯(cuò)誤導(dǎo)致的信號(hào),在信號(hào)處理函數(shù)中打印調(diào)用棧。如下代碼的信號(hào)處理函數(shù)是signalProc()。

void signalProc (int sig, siginfo_t* info, void* ptr)
{
    printf ("catch signal: %d\n", sig);

    // call backtrace() and backtrace_symbols() as above

    signal (sig, SIG_DFL);
    raise (sig);
}

void init (void)
{
  struct sigaction action;
  memset (&action, 0, sizeof(action));
  action.sa_sigaction = signalProc;
  action.sa_flags = SA_SIGINFO;

  sigaction (SIGSEGV, &action, NULL);
}

3. 分析Coredump的源代碼位置

運(yùn)行程序讓它Coredump,得到如下打印信息。可以看到崩潰的位置是0x1bd60。

========================================
catch signal: 11
si_signo = 11(SIGSEGV)
...
/lib/libc.so.6(+0x25040) [0xb53a6040]
./player(_ZN9PlayerEnd4initEv+0x178) [0x1bd60]
./player(_ZN9PlayerApp5startEv+0x40) [0x1a5e8]
/extp/pos/lib/libappfrm.so(_ZN6AppFrm3runEiPPc+0x88) [0xb57caf0c]
./player(main+0x34) [0x1a524]
/lib/libc.so.6(__libc_start_main+0x9d) [0xb5397776]
========================================

用addr2line 得到 0x1bd60對應(yīng)的源代碼位置,在函數(shù)PlayerEnd::init()中,文件PlayerEnd.cpp的第34行。

percherry@ubuntu:~/dev/pos_db$ arm-linux-gnueabi-addr2line -e apps/player/src/player -f -C 0x1bd60
PlayerEnd::init()
/home/percherry/dev/pos/apps/player/src/PlayerEnd.cpp:34

相關(guān)鏈接

GDB 常用法
GDB 調(diào)試Coredump問題
嵌入式開發(fā)中GDB調(diào)試Coredump問題
嵌入式開發(fā)中GDB串口遠(yuǎn)程調(diào)試
用backtrace()調(diào)試coredump問題
Valgrind memcheck 用法
Address Sanitizer 用法

參考資料

根據(jù)backtrace_symbols查錯(cuò)誤代碼行號(hào)
https://blog.csdn.net/download_73/article/details/75433589

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容