CRASH安裝和調試


一、Crash?

當linux系統內核發生崩潰的時候,可以通過KEXEC+KDUMP等方式收集內核崩潰之前的內存,生成一個轉儲elf文件vmcore或者其他dump形式。內核開發者通過分析該elf dump文件就可以診斷出內核崩潰的原因,從而進行操作系統的代碼問題修復。那么Crash就是一個被廣泛使用內核崩潰轉儲文件分析工具。

 

對調試來講,gdb/trace32是非常適合的,但gdb始終是調試native的工具,不支持kernel信息顯示,比如task信息之類的。crash補足了這個短板,由Dave Anderson開發和維護的一個內存轉儲分析工具,是基於GDB開發的,GDB適用於用戶進程的coredump,而Crash擴展了GDB,使其適用於linux kernel coredump,目前它的最新版本是7.3。在沒有統一標准的內存轉儲文件的格式的情況下,Crash工具支持眾多的內存轉儲文件格式,包括:

  • Live linux系統

  • kdump產生的正常的和壓縮的內存轉儲文件

  • 由makedumpfile命令生成的壓縮的內存轉儲文件

  • 由Netdump生成的內存轉儲文件

  • 由Diskdump生成的內存轉儲文件

  • 由Kdump生成的Xen的內存轉儲文件

  • IBM的390/390x的內存轉儲文件

  • LKCD生成的內存轉儲文件

  • Mcore生成的內存轉儲文件

二、安裝

crash是redhat開源工具,因此需要自己下載代碼編譯成linux可執行文件。

1)從官方網站下載crash源代碼;

git clone git://github.com/crash-utility/crash.git

2)編譯前確保必要的組件(ncurese和zlib);

    sudo apt-get install libncurses5-dev

    sudo apt-get install zlib1g-dev

3)解壓后編譯ARM 32bit的crash:

    cd crash-7.2.8

    make target=ARM64

4)如果是ARM 64bit的,則是:

    cd crash-7.2.8

    make target=ARM64

5)編譯后會在當前目錄下生成crash,可以將多余的符號去除:

    strip -s crash

6)當發生kernel crash時,會有db生成;

7)然后可以使用crash的各種命令了,詳情請看:http://people.redhat.com/anderson/crash_whitepaper/

三、調試

使用crash來調試vmcore,至少需要兩個參數:

  • NAMELIST:帶symbol的內核映像文件vmlinux,由內核調試信息包提供;

  • MEMORY-IMAGE:內存轉儲elf dump文件。

如果有使能KASLR 功能需要提供--kaslr 對應的offset地址:

Eg:./crash ../dump/vmlinux ../dump/DDRCS0_0.BIN@0x80000000,../dump/DDRCS0_1.BIN@0x100000000,../dump/DDRCS1_0.BIN@0x180000000,../dump/DDRCS1_1.BIN@0x200000000 --kaslr <kaslr_offset>  -m kimage_voffset=0xffffffe5d6200000 -m vabits_actual=39

注:vabits_actual=39 是VB_bits: CONFIG_ARM64_VA_BITS配置

基本輸出:

四、常用命令

crash使用gdb7.6作為它的內部引擎,crash中的很多命令和語法都與gdb相同。常用命令如下:如果想獲得crash更多的命令和相關命令的詳細說明,可以使用crash的內部命令help來獲取:

log | tail -n 100  查看log  cpu watdog bark觸發dump

struct msm_watchdog_data wdog_data查看wdog_data 狀態:

Non-secure Watchdog data

Pet time: 9.36s

Bark time: 20.0s

Watchdog last pet: 10741.000

Watchdog task running on core 2 from 10750.686741

CPUs responded to pet(alive_mask): 00000001

CPU which didn't respond to pet: 1

CPU#0 : ping_start: 10750.686769 : ping_end: 10750.686779

CPU#1 : ping_start: 10750.686780 : ping_end: 0.000000

 

ps | grep RU  查看cpu1上活躍進程狀態:

當前dump為cpu1 watchdog bark觸發 , 需要查看percpu變量irq_stat在cpu1 狀態, 使用per_cpu__ 加變量查看percpu 地址,新版本crash per_cpu已經能自動識別:

通過地址查看變量:__softirq_pending = 8 對應softirq 為 NET_RX

五、擴展命令

crash支持擴展命令,其中trace/gcore這2個命令對分析問題非常方便,其他具體請看crash擴展命令說明。

trace導出ftrace到FTRACE文件:

trace show > FTRACE

gcore導出init進程coredump [kernel中如有打開zram等類似功能,需要crash中添加對應解壓縮函數實現]:

gcore -f 255 1

使用擴展命令前,需要先編譯好對應的so庫,下面介紹如何編譯擴展命令的庫,以trace為例。

六、ftrace

ftrace對分析kernel性能和死機等問題非常重要,有些異常類問題需要借助mrdump查看ftrace。crash和T32都可以做到,這里講crash如何利用擴展命令支持查看ftrace。

1. 編譯擴展命令庫

1)trace擴展命令需要trace-cmd支持,先編譯trace-cmd

$git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git

pc端trace-cmd ,將生成的trace-cmd放到crash_master目錄

cd trace-cmd

make

手機端trace-cmd

cd trace-cmd

編譯32bit

make LDFLAGS=-static CC=<android codebase>/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gcc trace-cmd

編譯64bit

make LDFLAGS=-static CC=~/Android_tool/aarch64-linux-gnu-6.3.1/bin/aarch64-linux-gnu-gcc trace-cmd

2)編譯trace.so

將trace.c放入crash源碼里的extensions目錄,然后在crash源碼目錄下輸入如下命令:make extensions

編譯好后,就有so庫生成,文件放在extensions目錄,比如trace.so。

2. 使用擴展命令

進入crash前,需設定環境變量TRACE_CMD,否則使用時會有異常提示:

因此在啟動crash前,先:

exprot trace-cmd 環境變量 export TRACE_CMD=<path-to>/trace-cmd

 

進入crash后,在crash命令行添加擴展   extend <path-to>/trace.so

至此就可以正確使用trace擴展命令了,比如查看trace有哪些參數可以使用:

執行trace show如下:

參考材料

[1] http://people.redhat.com/anderson/

[2] https://www.dedoimedo.com/computers/crash-analyze.html#mozTocId904879

[3] https://github.com/crash-utility/crash

掃碼關注
“內核工匠”微信公眾號
Linux 內核黑科技 | 技術文章 | 精選教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM