問題背景
程式退出過程中卡死,但是一旦開啟 log 就無法復現問題。於是考慮獲取程式卡死時的 coredump 檔案,分析其呼叫棧。一種方法是在程式卡死時,用 kill
命令向其傳送一個訊號,使程式產生 coredump 檔案。
前提
- Target 上可以產生 core 檔案(如
/tmp/<executable-name>-<pid>.core
),如果沒有,檢查ulimit -c
設定
步驟
- 把 coredump 檔案從 target 拷到 host
- 假設用的交叉編譯器是
aarch64-unknown-nto-qnx7.1.0-gdb
,在 host 中執行aarch64-unknown-nto-qnx7.1.0-gdb <executable-file-path> <coredump-file-path>
- gdb 開始解析符號,如果提示 "Could not load shared library symbols for xxx libraries",則可以根據提示,設定這些庫所在 host 上的路徑
set solib-search-path <shared-library-path>
- 輸入
bt
命令即可檢視 backtrace
補充說明
- 交叉編譯時無需 -g 也可以獲取 backtrace 資訊
- 交叉編譯時即使使用了 -O2 最佳化選項,也可以獲取 backtrace 資訊
- 交叉編譯之後,target 上的動態庫、可執行檔案甚至可以是 strip 過的,不影響獲取 backtrace 資訊,只要保證 host 上的動態庫和可執行檔案沒有被 strip 即可
- 一些訊號不會產生 coredump 檔案,在我的環境下,傳送 SIGQUIT(3),SIGABRT(6), SIGKILL(9) 都沒有產生 coredump 檔案,而傳送 SIGSEGV(11)
kill -11 <PID>
是可以生成 coredump 檔案的