<< System語言詳解 >> 關於 SystemTap 的書。
我們在分析各種系統異常和故障的時候,通常會用到 pstack(jstack) /pldd/ lsof/ tcpdump/ gdb(jdb)/ netstat/vmstat/ mpstat/truss(strace)/iostat/sar/nmon(top)等系列工具,這些工具從某個方面為我們提供了診斷信息。但這些工具常常帶有各類“副作用”,比如 truss(見於 AIX/Solaris) 或者 strace(見於 Linux) 能夠讓我們檢測我們應用的系統調用情況,包括調用參數和返回值,但是卻會導致應用程序的性能下降;這對於診斷毫秒級響應的計費生產系統來說,影響巨大。有沒有一個工具,能夠兼得上述所有工具的優點,又沒有副作用呢?答案是有!對於 Solaris/BSD/OS X 系統來說,那就是 DTrace 工具(后來,Linux 也終於有了自己類似的工具,stap)。DTrace 的優勢是什么呢?可以這么講,如果你對於 OS 和應用熟悉,利用 DTrace 可以診斷所有問題;沒錯,是“所有”,“所有”,“所有”,重要的事情說三遍!
書籍:DTrace-Dynamic-Tracing-in-Oracle-Solaris-Mac-OS-X-and-FreeBSD.pdf
書籍:Solaris Dynamic Tracing Guide.pdf
腳本工具集合:DTraceToolkit-0.99
動態追蹤技術(中) - Dtrace、SystemTap、火焰圖
說到動態追蹤就不能不提到DTrace(1)。DTrace 算是現代動態追蹤技術的鼻祖了,它於 21 世紀初誕生於 Solaris 操作系統,是由原來的 Sun Microsystems 公司的工程師編寫的。可能很多同學都聽說過 Solaris 系統和 Sun 公司的大名。
最初產生的時候,我記得有這樣一個故事,當時 Solaris 操作系統的幾個工程師花了幾天幾夜去排查一個看似非常詭異的線上問題。開始他們以為是很高級的問題,就特別賣力,結果折騰了幾天,最后發現其實是一個非常愚蠢的、某個不起眼的地方的配置問題。自從那件事情之后,這些工程師就痛定思痛,創造了 DTrace 這樣一個非常高級的調試工具,來幫助他們在未來的工作當中避免把過多精力花費在愚蠢問題上面。畢竟大部分所謂的“詭異問題”其實都是低級問題,屬於那種“調不出來很郁悶,調出來了更郁悶”的類型。
應該說 DTrace 是一個非常通用的調試平台,它提供了一種很像 C 語言的腳本語言,叫做 D。基於 DTrace 的調試工具都是使用這種語言編寫的。D 語言支持特殊的語法用以指定“探針”,這個“探針”通常有一個位置描述的信息。你可以把它定位在某個內核函數的入口或出口,抑或是某個用戶態進程的 函數入口或出口,甚至是任意一條程序語句或機器指令上面。編寫 D 語言的調試程序是需要對系統有一定的了解和知識的。這些調試程序是我們重拾對復雜系統的洞察力的利器。Sun 公司有一位工程師叫做 Brendan Gregg,他是最初的 DTrace 的用戶,甚至早於 DTrace 被開源出來。Brendan 編寫了很多可以復用的基於 DTrace 的調試工具,一齊放在一個叫做DTrace Toolkit(2)的開源項目中。Dtrace 是最早的動態追蹤框架,也是最有名的一個。
DTrace 的優勢是它采取了跟操作系統內核緊密集成的一種方式。D 語言的實現其實是一個虛擬機(VM),有點像 Java 虛擬機(JVM)。它的一個好處在於 D 語言的運行時是常駐內核的,而且非常小巧,所以每個調試工具的啟動時間和退出時間都很短。但是我覺得 DTrace 也是有明顯缺點的。其中一個讓我很難受的缺點是 D 語言缺乏循環結構,這導致許多針對目標進程中的復雜數據結構的分析工具很難編寫。雖然 DTrace 官方聲稱缺少循環的原因是為了避免過熱的循環,但顯然 DTrace 是可以在 VM 級別上面有效限制每一個循環的執行次數的。另外一個較大的缺點是,DTrace 對於用戶態代碼的追蹤支持比較弱,沒有自動的加載用戶態調試符號的功能,需要自己在 D 語言里面聲明用到的用戶態 C 語言結構體之類的類型。
DTrace 的影響是非常大的,很多工程師把它移植到其他的操作系統。比方說蘋果的 Mac OS X 操作系統上就有 DTrace 的移植。其實近些年發布的每一台蘋果筆記本或者台式機上面,都有現成的 dtrace 命令行工具可以調用,大家可以去在蘋果機器的命令行終端上嘗試一下。這是蘋果系統上面的一個 DTrace 的移植。FreeBSD 操作系統也有這樣一個 DTrace 的移植。只不過它並不是默認啟用的。你需要通過命令去加載 FreeBSD 的 DTrace 內核模塊。Oracle 也有在它自己的 Oracle Linux 操作系統發行版當中開始針對 Linux 內核進行 DTrace 移植。不過 Oracle 的移植工作好像一直沒有多少起色,畢竟 Linux 內核並不是 Oracle 控制的,而 DTrace 是需要和操作系統內核緊密集成的。出於類似的原因,民間一些勇敢的工程師嘗試的 DTrace 的 Linux 移植也一直距離生產級別的要求很遠。
相比 Solaris 上面原生的 DTrace,這些 DTrace 移植都或多或少的缺乏某些高級特性,所以從能力上來說,還不及最本初的 DTrace。
DTrace 對 Linux 操作系統的另一個影響反映在SystemTap(3)這個開源項目。這是由 Red Hat 公司的工程師創建的較為獨立的動態追蹤框架。SystemTap 提供了自己的一種小語言(4),和 D 語言並不相同。顯然,Red Hat 自己服務於非常多的企業級用戶,他們的工程師每天需要處理的各種線上的“詭異問題”自然也是極多的。這種技術的產生必然是現實需求激發的。我覺得 SystemTap 是目前 Linux 世界功能最強大,同時也是最實用的動態追蹤框架。我在自己的工作當中已經成功使用多年。SystemTap 的作者 Frank Ch. Eigler 和 Josh Stone 等人,都是非常熱情、同時非常聰明的工程師。我在 IRC 或者郵件列表里的提問,他們一般都會非常快且非常詳盡地進行解答。值得一提的是,我也曾給 SystemTap 貢獻過一個較為重要的新特性,使其能在任意的探針上下文中訪問用戶態的全局變量的取值。我當時合並到 SystemTap 主線的這個C++ 補丁(5)的規模達到了約一千行,多虧了 SystemTap 作者們的熱心幫助。這個新特性在我基於 SystemTap 實現的動態腳本語言(比如 Perl 和 Lua)的火焰圖(6)工具中扮演了關鍵角色。
SystemTap 的優點是它有非常成熟的用戶態調試符號的自動加載,同時也有循環這樣的語言結構可以去編寫比較復雜的探針處理程序,可以支持很多很復雜的分析處理。由於 SystemTap 早些年在實現上的不成熟,導致互聯網上充斥着很多針對它的已經過時了的詬病和批評。最近幾年 SystemTap 已然有了長足的進步。
當然,SystemTap 也是有缺點的。首先,它並不是 Linux 內核的一部分,就是說它並沒有與內核緊密集成,所以它需要一直不停地追趕主線內核的變化。另一個缺點是,它通常是把它的“小語言”腳本(有點像 D 語言哦)動態編譯成一個 Linux 內核模塊的 C 源碼,因此經常需要在線部署 C 編譯器工具鏈和 Linux 內核的頭文件,同時需要動態地加載這些編譯出來的內核模塊,以運行我們的調試邏輯。在我們的調試工具運行完畢之后,又存在動態卸載 Linux 內核模塊的問題。出於這些原因,SystemTap 腳本的啟動相比 DTrace 要慢得多,和 JVM 的啟動時間倒有幾分類似。雖然存在這些缺點,但總的來說,SystemTap 還是一個非常成熟的動態追蹤框架。
無論是 DTrace 還是 SystemTap,其實都不支持編寫完整的調試工具,因為它們都缺少方便的命令行交互的原語。所以我們才看到現實世界中許多基於它們的工具,其實最外面都有一個 Perl、Python 或者 Shell 腳本編寫的包裹。為了便於使用一種干凈的語言編寫完整的調試工具,我曾經給 SystemTap 語言進行了擴展,實現了一個更高層的“宏語言”,叫做stap++(7)。我自己用 Perl 實現的 stap++ 解釋器可以直接解釋執行 stap++ 源碼,並在內部調用 SystemTap 命令行工具。有興趣的朋友可以查看我開源在 GitHub 上面的 stapxx 這個代碼倉庫。這個倉庫里面也包含了很多直接使用我的 stap++ 宏語言實現的完整的調試工具。
SystemTap 在生產上的應用
DTrace 有今天這么大的影響離不開著名的 DTrace 布道士Brendan Gregg(8)老師。前面我們也提到了他的名字。他最初是在 Sun Microsystems 公司,工作在 Solaris 的文件系統優化團隊,是最早的 DTrace 用戶。他寫過好幾本有關 DTrace 和性能優化方面的書,也寫過很多動態追蹤方面的博客文章。
2011 年我離開淘寶以后,曾經在福州過了一年所謂的“田園生活”。在田園生活的最后幾個月當中,我通過 Brendan 的公開博客(9)較為系統地學習了 DTrace 和動態追蹤技術。其實最早聽說 DTrace 是因為一位微博好友的評論,他只提到了 DTrace 這個名字。於是我便想了解一下這究竟是什么東西。誰知,不了解不知道,一了解嚇一跳。這竟然是一個全新的世界,徹底改變了我對整個計算世界的看法。於是我就花了非常多的時間,一篇一篇地仔細精讀 Brendan 的個人博客。后來終於有一天,我有了一種大徹大悟的感覺,終於可以融會貫通,掌握到了動態追蹤技術的精妙。
2012 年我結束了在福州的“田園生活”,來到美國加入目前這家 CDN 公司。然后我就立即開始着手把 SystemTap 以及我已領悟到的動態追蹤的一整套方法,應用到這家 CDN 公司的全球網絡當中去,用於解決那些非常詭異非常奇怪的線上問題。我在這家公司觀察到其實很多工程師在排查線上問題的時候,經常會自己在軟件系統里面埋點。這主要是在業務代碼里,乃至於像 Nginx 這樣的系統軟件的代碼基(code base)里,自己去做修改,添加一些計數器,或者去埋下一些記錄日志的點。通過這種方式,大量的日志會在線上被實時地采集起來,進入專門的數據庫,然后再進行離線分析。顯然這種做法的成本是巨大的,不僅涉及業務系統本身的修改和維護成本的陡然提高,而且全量采集和存儲大量的埋點信息的在線開銷,也是非常可觀的。而且經常出現的情況是,張三今天在業務代碼里面埋了一個采集點,李四明天又埋下另一個相似的點,事后可能這些點又都被遺忘在了代碼基里面,而沒有人再去理會。最后這種點會越來越多,把代碼基搞得越來越凌亂。這種侵入式的修改,會導致相應的軟件,無論是系統軟件還是業務代碼,變得越來越難以維護。
埋點的方式主要存在兩大問題,一個是“太多”的問題,一個是“太少”的問題。“太多”是指我們往往會采集一些根本不需要的信息,只是一時貪多貪全,從而造成不必要的采集和存儲開銷。很多時候我們通過采樣就能進行分析的問題,可能會習慣性的進行全網全量的采集,這種代價累積起來顯然是非常昂貴的。那“太少”的問題是指,我們往往很難在一開始就規划好所需的所有信息采集點,畢竟沒有人是先知,可以預知未來需要排查的問題。所以當我們遇到新問題時,現有的采集點搜集到的信息幾乎總是不夠用的。這就導致頻繁地修改軟件系統,頻繁地進行上線操作,大大增加了開發工程師和運維工程師的工作量,同時增加了線上發生更大故障的風險。
另外一種暴力調試的做法也是我們某些運維工程師經常采用的,即把機器拉下線,然后設置一系列臨時的防火牆規則,以屏蔽用戶流量或者自己的監控流量,然后在生產機上各種折騰。這是很繁瑣影響很大的過程。首先它會讓機器不能再繼續服務,降低了整個在線系統的總的吞吐能力。同時有些只有真實流量才能復現的問題,此時再也無法復現了。可以想象這些粗暴的做法有多么讓人頭疼。
實際上運用 SystemTap 動態追蹤技術可以很好地解決這樣的問題,有“潤物細無聲”之妙。首先我們不需要去修改我們的軟件棧(software stack)本身,不管是系統軟件還是業務軟件。我經常會編寫一些有針對性的工具,然后在一些關鍵的系統「穴位」上面放置一些經過仔細安排的探針。這些探針會采集各自的信息,同時調試工具會把這些信息匯總起來輸出到終端。用這種方式我可以在某一台機器或某幾台機器上面,通過采樣的方式,很快地得到我想要的關鍵信息,從而快速地回答一些非常基本的問題,給后續的調試工作指明方向。
正如我前面提到的,與其在生產系統里面人工去埋點去記日志,再搜集日志入庫,還不如把整個生產系統本身看成是一個可以直接查詢的“數據庫”,我們直接從這個“數據庫”里安全快捷地得到我們想要的信息,而且絕不留痕跡,絕不去采集我們不需要的信息。利用這種思想,我編寫了很多調試工具,絕大部分已經開源在了 GitHub 上面,很多是針對像 Nginx、LuaJIT 和操作系統內核這樣的系統軟件,也有一些是針對更高層面的像 OpenResty 這樣的 Web 框架。有興趣的朋友可以查看 GitHub 上面的nginx-systemtap-toolkit(10)、perl-systemtap-toolkit(11)和stappxx(12)這幾個代碼倉庫。
我的 SystemTap 工具雲
利用這些工具,我成功地定位了數不清的線上問題,有些問題甚至是我意外發現的。下面就隨便舉幾個例子吧。
第一個例子是,我使用基於 SystemTap 的火焰圖工具分析我們線上的 Nginx 進程,結果發現有相當一部分 CPU 時間花費在了一條非常奇怪的代碼路徑上面。這其實是我一位同事在很久之前調試一個老問題時遺留下來的臨時的調試代碼,有點兒像我們前面提到的“埋點代碼”。結果它就這樣被遺忘在了線上,遺忘在了公司代碼倉庫里,雖然當時那個問題其實早已解決。由於這個代價高昂的“埋點代碼”一直沒有去除,所以一直都產生着較大的性能損耗,而一直都沒有人注意到。所以可謂是我意外的發現。當時我就是通過采樣的方式,讓工具自動繪制出一張火焰圖。我一看這張圖就可以發現問題並能采取措施。這是非常非常有效的方式。
第二個例子是,很少量的請求存在延時較長的問題,即所謂的“長尾請求”。這些請求數目很低,但可能達到「秒級」這樣的延時。當時有同事亂猜說是我的 OpenResty 有 bug,我不服氣,於是立即編寫了一個 SystemTap 工具去在線進行采樣,對那些超過一秒總延時的請求進行分析。該工具會直接測試這些問題請求內部的時間分布,包括請求處理過程中各個典型 I/O 操作的延時以及純 CPU 計算延時。結果很快定位到是 OpenResty 在訪問 Go 編寫的 DNS 服務器時,出現延時緩慢。然后我再讓我的工具輸出這些長尾 DNS 查詢的具體內容,發現都是涉及 CNAME 展開。顯然,這與OpenResty 無關了,而進一步的排查和優化也有了明確的方向。
第三個例子是,我們曾注意到某一個機房的機器存在比例明顯高於其他機房的網絡超時的問題,但也只有 1% 的比例。一開始我們很自然的去懷疑網絡協議棧方面的細節。但后來我通過一系列專門的 SystemTap 工具直接分析那些超時請求的內部細節,便定位到了是硬盤 配置方面的問題。從網絡到硬盤,這種調試是非常有趣的。第一手的數據讓我們快速走上正確的軌道。
還有一個例子是,我們曾經通過火焰圖在 Nginx 進程里觀察到文件的打開和關閉操作占用了較多的 CPU 時間,於是我們很自然地啟用了 Nginx 自身的文件句柄緩存配置,但是優化效果並不明顯。於是再做出一張新的火焰圖,便發現因為這回輪到 Nginx 的文件句柄緩存的元數據所使用的“自旋鎖”占用很多 CPU 時間了。這是因為我們雖然啟用了緩存,但把緩存的大小設置得過大,所以導致元數據的自旋鎖的開銷抵消掉了緩存帶來的好處。這一切都能在火焰圖上面一目了然地看出來。假設我們沒有火焰圖,而只是盲目地試驗,很可能會得出 Nginx 的文件句柄緩存沒用的錯誤結論,而不會去想到去調整緩存的參數。
最后一個例子是,我們在某一次上線操作之后,在線上最新的火焰圖中觀察到正則表達式的編譯操作占用了很多 CPU 時間,但其實我們已經在線上啟用了正則編譯結果的緩存。很顯然,我們業務系統中用到的正則表達式的數量,已然超出了我們最初設置的緩存大小,於是很自然地想到把線上的正則緩存調的更大一些。然后,我們在線上的火焰圖中便再看不到正則編譯操作了。
通過這些例子我們其實可以看到,不同的數據中心,不同的機器,乃至同一台機器的不同時段,都會產生自己特有的一些新問題。我們需要的是直接對問題本身進行分析,進行采樣,而不是胡亂去猜測去試錯。有了強大的工具,排錯其實是一個事半功倍的事情。
火焰圖
前面我們已經多次提到了火焰圖(Flame Graph)這種東西(systemtap 可以制作火焰圖, perf 命令也可以制作火焰圖),那么火焰圖是什么呢?它其實是一個非常了不起的可視化方法,是由前面已經反復提到的 Brendan Gregg 同學發明的。
火焰圖就像是給一個軟件系統拍的 X 光照片,可以很自然地把時間和空間兩個維度上的信息融合在一張圖上,以非常直觀的形式展現出來,從而反映系統在性能方面的很多定量的統計規律。
Nginx 的 C 級別 on-CPU 火焰圖示例
比方說,最經典的火焰圖是統計某一個軟件的所有代碼路徑在 CPU 上面的時間分布。通過這張分布圖我們就可以直觀地看出哪些代碼路徑花費的 CPU 時間較多,而哪些則是無關緊要的。進一步地,我們可以在不同的軟件層面上生成火焰圖,比如說可以在系統軟件的 C/C++ 語言層面上畫出一張圖,然后再在更高的——比如說——動態腳本語言的層面,例如 Lua 和 Perl 代碼的層面,畫出火焰圖。不同層面的火焰圖常常會提供不同的視角,從而反映出不同層面上的代碼熱點。
因為我自己維護着 OpenResty 這樣的開源軟件的社區,我們有自己的郵件列表,我經常會鼓勵報告問題的用戶主動提供自己繪制的火焰圖,這樣我們就可以愜意地看圖說話(13),幫助用戶快速地進行性能問題的定位,而不至於反復地試錯,和用戶一起去胡亂猜測,從而節約彼此大量的時間,皆大歡喜。
這里值得注意的是,即使是遇到我們並不了解的陌生程序,通過看火焰圖,也可以大致推出性能問題的所在,即使從未閱讀過它的一行源碼。這是一件非常了不起的事情。因為大部分程序其實是編寫良好的,也就是說它往往在軟件構造的時候就使用了抽象層次,比如通過函數。這些函數的名稱通常會包含語義上的信息,並在火焰圖上面直接顯示出來。通過這些函數名,我們可以大致推測出對應的函數,乃至對應的某一條代碼路徑,大致是做什么事情的,從而推斷出這個程序所存在的性能問題。所以,又回到那句老話,程序代碼中的命名非常重要,不僅有助於閱讀源碼,也有助於調試問題。而反過來,火焰圖也為我們提供了一條學習陌生的軟件系統的捷徑。畢竟重要的代碼路徑,幾乎總是花費時間較多的那些,所以值得我們重點研究;否則的話,這個軟件的構造方式必然存在很大的問題。
火焰圖其實可以拓展到其他維度,比如剛才我們講的火焰圖是看程序運行在 CPU 上的時間在所有代碼路徑上的分布,這是 on-CPU 時間這個維度。類似地,某一個進程不運行在任何 CPU 上的時間其實也是非常有趣的,我們稱之為 off-CPU 時間。off-CPU 時間一般是這個進程因為某種原因處於休眠狀態,比如說在等待某一個系統級別的鎖,或者被一個非常繁忙的進程調度器(scheduler)強行剝奪 CPU 時間片。這些情況都會導致這個進程無法運行在 CPU 上,但是仍然花費很多的掛鍾時間。通過這個維度的火焰圖我們可以得到另一幅很不一樣的圖景。通過這個維度上的信息,我們可以分析系統鎖方面的開銷(比如sem_wait
這樣的系統調用),某些阻塞的 I/O 操作(例如open
、read
之類),還可以分析進程或線程之間爭用 CPU 的問題。通過 off-CPU 火焰圖,都一目了然。
應該說 off-CPU 火焰圖也算是我自己的一個大膽嘗試。記得最初我在加州和內華達州之間的一個叫做 Tahoe 的湖泊邊,閱讀 Brendan 關於 off-CPU 時間的一篇博客文章(14)。我當然就想到,或許可以把 off-CPU 時間代替 on-CPU 時間應用到火焰圖這種展現方式上去。於是回來后我就在公司的生產系統中做了這樣一個嘗試,使用 SystemTap 繪制出了 Nginx 進程的 off-CPU 火焰圖。我在推特上公布了這個成功嘗試之后,Brendan 還專門聯系到我,說他自己之前也嘗試過這種方式,但效果並不理想。我估計這是因為他當時將之應用於多線程的程序,比如 MySQL,而多線程的程序因為線程同步方面的原因,off-CPU 圖上會有很多噪音,容易掩蓋真正有趣的那些部分。而我應用 off-CPU 火焰圖的場景是像 Nginx 這樣的單線程程序,所以 off-CPU 火焰圖里往往會立即指示出那些阻塞 Nginx 事件循環的系統調用,抑或是sem_wait
之類的鎖操作,又或者是搶占式的進程調度器的強行介入,於是可以非常好地幫助分析一大類的性能問題。在這樣的 off-CPU 火焰圖中,唯一的“噪音”其實就是 Nginx 事件循環本身的epoll_wait
這樣的系統調用,很容易識別並忽略掉。
內核的內存轉儲機制
由於 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 相比,它有以下特點:
- 將內存保存到磁盤。
- 可以將內存轉儲鏡像轉換到 lcrash 支持格式。
- 通過 kexec 啟動時,mini 內核覆蓋第一個內核。
各種內存轉儲分析工具
與具有眾多的內存轉儲機制一樣,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 工具支持眾多的內存轉儲文件格式,包括:
- Live linux 系統
- kdump 產生的正常的和壓縮的內存轉儲文件
- 由 makedumpfile 命令生成的壓縮的內存轉儲文件
- 由 Netdump 生成的內存轉儲文件
- 由 Diskdump 生成的內存轉儲文件
- 由 Kdump 生成的 Xen 的內存轉儲文件
- IBM 的 390/390x 的內存轉儲文件
- LKCD 生成的內存轉儲文件
- Mcore 生成的內存轉儲文件