使用 Crash 工具分析 Linux dump 文件

2021-02-13 Linux知識積累
前言

Linux 內核(以下簡稱內核)是一個不與特定進程相關的功能集合,內核的代碼很難輕易的在調試器中執行和跟蹤。開發者認為,內核如果發生了錯誤,就不應該繼續運行。因此內核發生錯誤時,它的行為通常被設定為系統崩潰,機器重啟。基於動態存儲器的電氣特性,機器重啟後,上次錯誤發生時的現場會遭到破壞,這使得查找內核的錯誤變得異常困難。

內核社區和一些商業公司為此開發了很多種調試技術和工具,希望可以讓內核的調試變得簡單。其中一種是單步跟蹤調試方法,即使用代碼調試器,一步步的跟蹤執行的代碼,通過查看變量和寄存器的值來分析錯誤發生的原因。這一類的調試器有 gdb,kdb, kgdb。另一種方法是在系統崩潰時,將內存保存起來,供事後進行分析。多數情況下,單步調式跟蹤可以滿足需求,但是單步跟蹤調試也有缺點。如遇到如下幾種情況時:

錯誤發生在客戶的機器上。

錯誤發生在很關鍵的生產機器上。

錯誤很難重現。

單步調試跟蹤方法將無能為力。對於這幾種情況,在內核發生錯誤並崩潰的時候,將內存轉儲起來供事後分析就顯得尤為重要。本文接下來將介紹內核的內存轉儲機制以及如何對其進行分析。

內核的內存轉儲機制

由於 Linux 的開放性的緣故,在 Linux 下有好幾種內存轉儲機制。下面將對它們分別做簡要的介紹。

LKCD

LKCD(Linux Kernel Crash Dump) 是 Linux 下第一個內核崩潰內存轉儲項目,它最初由 SGI 的工程師開發和維護。它提供了一種可靠的方法來發現、保存和檢查系統的崩潰。LKCD 作為 Linux 內核的一個補丁,它一直以來都沒有被接收進入內核的主線。目前該項目已經完全停止開發。

Diskdump

Diskdump 是另外一個內核崩潰內存轉儲的內核補丁,它由塔高 (Takao Indoh) 在 2004 年開發出來。與 LKCD 相比,Diskdump 更加簡單。當系統崩潰時,Diskdump 對系統有完全的控制。為避免混亂,它首先關閉所有的中斷;在 SMP 系統上,它還會把其他的 CPU 停掉。然後它校驗它自己的代碼,如果代碼與初始化時不一樣。它會認為它已經被破壞,並拒絕繼續運行。然後 Diskdump 選擇一個位置來存放內存轉儲。Diskdump 作為一個內核的補丁,也沒有被接收進入內核的主線。在眾多的發行版中,它也只得到了 RedHat 的支持。

Netdump

RedHat 在它的 Linux 高級伺服器 2.1 的版本中,提供了它自己的第一個內核崩潰內存轉儲機制:Netdump。 與 LKCD 和 Diskdump 將內存轉儲保存在本地磁碟不同,當系統崩潰時,Netdump 將內存轉儲文件通過網絡保存到遠程機器中。RedHat 認為採用網絡方式比採用磁碟保的方式要簡單,因為當系統崩潰時,可以在沒有中斷的情況下使用網卡的論詢模式來進行網絡數據傳送。同時,網絡方式對內存轉儲文件提供了更好的管理支持。與 Diskdump 一樣,Netdump 沒有被接收進入內核的主線,目前也只有 RedHat 的發行版對 Netdump 提供支持。

Kdump

Kdump 是一種基於 kexec 的內存轉儲工具,目前它已經被內核主線接收,成為了內核的一部分,它也由此獲得了絕大多數 Linux 發行版的支持。與傳統的內存轉儲機制不同不同,基於 Kdump 的系統工作的時候需要兩個內核,一個稱為系統內核,即系統正常工作時運行的內核;另外一個稱為捕獲內核,即正常內核崩潰時,用來進行內存轉儲的內核。 在本文稍後的內容中,將會介紹如何設置 kump。

MKdump

MKdump(mini kernel dump) 是 NTT 數據和 VA Linux 開發另一個內核內存轉儲工具,它與 Kdump 類似,都是基於 kexec,都需要使用兩個內核來工作。其中一個是系統內核;另外一個是 mini 內核,用來進行內存轉儲。與 Kdump 相比,它有以下特點:

各種內存轉儲分析工具

與具有眾多的內存轉儲機制一樣,Linux 下也有眾多的內存轉儲分析工具,下面將會逐一做簡單介紹。

Lcrash

Lcrash 是隨 LKCD 一起發布的一個內內存儲分析工具。隨著 LKCD 開發的停止,lcrash 的開發也同時停止了。目前它的代碼已經被合併進入 Crash 工具中。

Alicia

Alicia (Advanced Linux Crash-dump Interactive Analyzer,高級 Linux 崩潰內存轉儲交互分析器 ) 是一個建立在 lcrash 和 Crash 工具之上的一個內存轉儲分析工具。它使用 Perl 語言封裝了 Lcrash 和 Crash 的底層命令,向用戶提供了一個更加友好的交互方式和界面。Alicia 目前的開發也已經停滯。

Crash

Crash 是由 Dave Anderson 開發和維護的一個內存轉儲分析工具,目前它的最新版本是 5.0.0。 在沒有統一標準的內存轉儲文件的格式的情況下,Crash 工具支持眾多的內存轉儲文件格式,包括:

使用 Crash 分析內存轉儲文件的例子

通過前面的學習,你現在可能已經躍躍欲試了。本文接下來的部分,將以 kdump 為例子,向大家演示如何設置系統、如何產生內存轉儲文件以及如何對內存轉儲文件進行分析。

kdump 的安裝設置

如前面所述,支持 kdump 的系統使用兩個內核進行工作。目前一些發行版,如 RedHat 和 SUSE 的 Linux 都已經編譯並設置好這兩個內核。如果你使用其他發行版的 Linux 或者想自己編譯內核支持 kdump,那麼可以根據如下介紹進行。

安裝 kexec

使用 root 用戶登錄系統。

使用 wget 從 Internet 上下載 kexec。

1

2

wget http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/\

 kexec-tools.tar.gz

解壓並安裝 kexec 到系統中。

1

2

3

4

# tar xvpzf kexec-tools.tar.gz

# cd kexec-tools-VERSION

# ./configure

# make && make install

配置系統內核和捕捉內核都需要的內核選項:

在 "Processor type and features."選項中啟用"kexec system call"。

在"Filesystem" -> "Pseudo filesystems." 中啟用"sysfs file system support"。

在"Kernel hacking."中啟用"Compile the kernel with debug info"。

配置捕捉內核的與架構無關的選項:配置捕捉內核的與架構相關的選項:

Linux 內核支持多種 CPU 架構,這裡只介紹捕捉內核在 i386 下的配置

在"Processor type and features"中啟用高端內存支持。

在"Processor type and features"中關閉多處理器支持。

在"Processor type and features"中啟用"Build a relocatable kernel"。

在"Processor type and features"->"Physical address where the kernel is loaded"中,為內核設置一個加載起始地址。在大多數的機器上,16M 是一個合適的值。

1

CONFIG_PHYSICAL_START=0x1000000

加載新的系統內核

編譯系統內核和捕捉內核。

將重新編譯好的內核添加到啟動引導中,注意不要將捕捉內核添加到啟動引導菜單中。

給系統內核添加啟動參數"crashkernel=Y@X",這裡,Y 是為 dump 捕捉內核保留的內存,X 是保留部分內存的開始位置。在 i386 的機器上,設置"crashkernel=64M@16M"。

重啟機器,在啟動菜單中選擇新添加的啟動項,啟動新的系統內核。

加載捕捉內核

在系統內核引導完成後,需要將捕捉內核加載到內存中。使用 kexec 工具將捕捉內核加載到內存:

1

2

3

# kexec -p <dump-capture-kernel-bzImage> \

 --initrd=<initrd-for-dump-capture-kernel> \

 --append="root=<root-dev> <arch-specific-options>"

觸發內核崩潰

在捕捉內核被加載進入內存後,如果系統崩潰開關被觸發,則系統會自動切換進入捕捉內核。觸發系統崩潰的開關有 panic(),die(),die_nmi() 內核函數和 sysrq 觸發事件,可以使用其中任意的一個來觸發內核崩潰。不過,在讓內核崩潰之前,我們還需要做一些安裝設置。

Crash 工具的安裝設置

Crash 目前的最新的版本是 5.0.0, 你可以從它的官方網站下載最新的版本。下載完成後對其進行解壓安裝。

1

2

3

4

# tar -zvxf crash-5.0.0.tar.gz

# cd crash-5.0.0

# ./configure

# make &&make install

生成內存轉儲文件

現在已經設置好 Kdump 和 crash,現在可以使用前面介紹的系統崩潰開關中的任意一個來引發系統崩潰來生成一個內存轉儲文件,並可以使用 crash 對其進行分析。

首先,觸發系統崩潰,這裡使用 sysrq 觸發事件。

1

# echo c > /proc/sysrq-trigger

緊接著,系統會自動啟動捕捉內核。待完全啟動進入捕捉內核後,通過以下命令保存內存轉儲文件。

1

# cp /proc/vmcore mydumpfile

將在當前目錄生成一個 mydumpfile 文件。

分析內存轉儲文件

現在有了一個內存轉儲文件,接下來使用 crash 對其進行分析

1

# crash vmlinux mydumpfile

這裡 vmlinux 是帶調試信息的內核。如果一切正常,將會進入到 crash 中,如圖 1 所示。

圖 1. crash 命令提示符

在該提示符下,可以執行 crash 的內部命令。通過 crash 的內部命令,可以查看寄存器的值、函數的調用堆棧等信息。在圖 2 中,顯示了執行 bt命令後得到的函數調用的堆棧信息。

圖 2. 函數調用堆棧信息

crash 使用 gdb 作為它的內部引擎,crash 中的很多命令和語法都與 gdb 相同。如果你曾經使用過 gdb,就會發現 crash 並不是很陌生。如果想獲得 crash 更多的命令和相關命令的詳細說明,可以使用 crash 的內部命令 help來獲取。

後記

本文介紹了 Linux 下的各種內存轉儲機制,以及如何 crash 工具開對內存轉儲文件進行分析。內核雖然複雜,但通過結合使用內核的內存轉儲文件和 crash 分析工具,可以輕鬆的找到內核問題的所在。通過對這篇文章的學習,相信你也可以像一個專業的內核開發者那樣去追蹤和修復內核的錯誤了。

相關焦點

  • 使用Crash工具分析 Linux dump文件
    與 Kdump 相比,它有以下特點: 各種內存轉儲分析工具與具有眾多的內存轉儲機制一樣,Linux 下也有眾多的內存轉儲分析工具,下面將會逐一做簡單介紹。LcrashLcrash 是隨 LKCD 一起發布的一個內內存儲分析工具。隨著 LKCD 開發的停止,lcrash 的開發也同時停止了。
  • [譯]《iOS Crash Dump Analysis》- 符號化
    它實際上只是因為這個命令: dsymutil path_to_app_binary -o output_symbols_dir.dSYM著手符號化為了幫助我們熟悉 crash dump 報告,我們可以演示實際上符號化是如何工作的。
  • xCrash 詳解與源碼分析
    當我們的應用發生錯誤或者崩潰時,如果有一款趁手的日誌捕獲工具,那將會得心應手的多。今天要學習的是來自 IQiYi 的 xCrash 日誌捕獲工具。這款工具不管是從質量上還是功能上,都是上乘之作。其中最重要的是初始化了兩個文件 fd ,以應對文件 fd 被耗盡的情況。
  • [譯]《iOS Crash Dump Analysis》- Siri崩潰
    請注意,Mac 上的二進位文件未加密。這意味著我們可以演示如何使用第三方工具來研究出錯的二進位文件。但由於只有 Apple 擁有 Siri 的原始碼,因此它增加了挑戰難度,並迫使我們對問題進行抽象思考。
  • Android基礎開發實踐:如何分析Native Crash
    關於tombstone文件的詳細解讀,可以參考:https://source.android.com/devices/tech/debug/native-crash#crashdump分析tombstone文件時
  • 【Linux內存分析工具】Volatility
    本次討論主要基於Linux下Volatility的分析。    Volatility有豐富的插件命令,能夠加載相應的配置文件profile 進行加載插件。需要特別說明的是,windows系統的profiles相當齊全,但linux下的profile就得自己製作了。
  • WinDBG 分析鍵盤生成的 Dump 文件
    本文介紹如何使用USB 鍵盤在 Windows 下生成一個 Dump 文件,然後通過工具進行分析。
  • 滲透技巧——使用Mimilib從dump文件中導出口令
    0x00 前言在上篇文章《Mimilib利用分析》提到mimilib可作為WinDbg的插件進行使用,所以本文將會詳細介紹這個插件的用法,實現從內核模式轉儲文件中導出口令,結合利用思路給出防禦建議。0x01 簡介本文將要介紹以下內容:· dump文件的分類· 兩種dump文件的導出方法· WinDbg環境配置· 利用思路·
  • Linux Core Dump
    dump 出來的內容是格式化的,可以使用一些工具來解析它。現代作業系統中,用 Core Dump 表示當程序異常終止或崩潰時,將進程此時的內存中的內容拷貝到磁碟文件中存儲,以方便編程人員調試。Dump我使用的 Linux 發行版是 Ubuntu 13.04,設置生成 core dump 文件的方法如下:打開 core dump 功能在終端中輸入命令 ulimit -c ,輸出的結果為 0,說明默認是關閉 core dump 的,即當程序異常終止時,也不會生成 core dump 文件。
  • Android 巧用 adb logcat 工具查看丟失的 app crash 數據
    Android App 運營期間發生崩潰是在所難免的事情,問題在於如何獲取崩潰日誌,進而分析解決問題。
  • 愛奇藝 Xcrash 是怎麼捕獲 crash 的
    Xcrash分別關聯三種類型Handler來處理對應的奔潰監聽和日誌收集,通過FileManager和TombstoneManager對奔潰日誌進行tombstone文件管理。client調用TombstoneParser來解析本地生成的對應tombstone文件,獲取數據。四、捕獲Java奔潰Java層的崩潰可以直接交給JVM的崩潰捕獲機制去處理。這個非常簡單,不贅述。
  • 使用crash工具看懂slab
    參考Linux內核代碼: 3.10cra
  • Linux下分析bin文件的10種方法
    二進位文件是我們幾乎每天都需要打交道的文件類型,但很少人知道他們的工作原理。這裡所講的二進位文件,是指一些可執行文件,包括你天天要使用的 Linux 命令,也是二進位文件的一種。Linux 系統給我們提供了非常多用於分析二進位文件的工具,不管你在 Linux 下從事的是何種工作,知道這些工具也會讓你對你的系統更加了解。
  • iOS Crash 分析攻略
    在這一點上, KSCrash 提供了分析功能, 可以對寄存器內值的意義進一步分析,比如分析是不是一個 ObjC 的對象,分析string的內容,可以幫助我們對Crash進一步分析,因為 Crash 現場如果能拿到更多的信息,對於定位 Crash 的幫助可能是很大的,這個功能是很贊的。
  • 使用 redis-rdb-tools 解析 reids dump.rdb 文件及分析內存使用量
    現在越來越多人開始使用 Redis 了,主要是因為它十分高效、性能強勁、擴展性好。先介紹幾種分析 Redis 的工具!
  • 藍隊安全 : 內存取證(下-分析內存)
    在我們的上一篇 藍隊安全 : 內存取證(上-獲得內存) 中我們講解並實戰了在不同系統平臺下獲得內存的方法,本次我們就著手分析 dump 出來的內存文件,在實戰中進一步的學習內存取證的知識點.VolatilityVolatility,作為內存取證最為常用的工具,是必須要掌握的。
  • 使用開源工具進行 Linux 內存取證 | Linux 中國
    計算機的作業系統和應用使用主內存(RAM)來執行不同的任務。這種易失性內存包含大量關於運行應用、網絡連接、內核模塊、打開的文件以及幾乎所有其他的內容信息,但這些信息每次計算機重啟的時候都會被清除。內存取證(Memory forensics)是一種從內存中找到和抽取這些有價值的信息的方式。Volatility 是一種使用插件來處理這類信息的開源工具。
  • iOS實錄14:淺談iOS Crash
    此處是 x0000000100028000 + 1954432, 第一個數字指向文件,第二個數字指向文件中的代碼行。說明1:線程回溯部分並不是我們習慣使用方法名和行數,而是十六進位地址。所以我們在分析Crash前需要將這些十六進位地址轉化成方法名稱和行數,改過程被稱為符號化。
  • 我偶爾會用到的調試方法 | Linux 內核
    因為它會時刻提醒你平時寫代碼時要謹慎、要多看書、多去認識一些更資深的人,別問我為什麼會有這樣的感受,因為是親身經歷~掌握一個調試工具是需要學習成本的,這裡只是列舉我自己會用到的工具,如果有某個你覺得特別牛逼的工具而我沒提到的話,請原諒我。
  • Node常用dump分析
    Dump類型詳細信息可以參考文末連結Dump作用Dump準備Dump分析示例Heap dump分析模擬內存洩漏,分析heapdump