Linux 內核測試與調試(3)

2022-01-10 Linux中國
基本測試

安裝好內核後,試試能不能啟動它。能啟動的話,檢查 dmesg 看看有沒有隱藏的錯誤。試試下面的功能:

檢查內核日誌

使用 dmesg 查看隱藏的問題,對於定位新代碼帶來的 bug 是一個好方法。一般來說,dmesg 不會輸出新的 crit, alert, emerg 級別的錯誤信息,也不應該出現新的 err 級別的信息。你要注意的是那些 warn 級別的日誌信息。請注意 warn 這個級別的信息並不是壞消息,新代碼帶來新的警告信息,不會給內核帶去嚴重的影響。

dmesg -t -l emerg

dmesg -t -l crit

dmesg -t -l alert

dmesg -t -l err

dmesg -t -l warn

dmesg -t -k

dmesg -t

下面的腳本運行了上面的命令,並且將輸出保存起來,以便與老的內核的 dmesg 輸出作比較(LCTT:老內核的 dmesg 輸出在本系列的第二篇文章中有介紹)。然後運行 diff 命令,查看新老內核 dmesg 日誌之間的不同。這個腳本需要輸入老內核版本號,如果不輸入參數,它只會生成新內核的 dmesg 日誌文件後直接退出,不再作比較(LCTT:話是這麼說沒錯,但點開腳本一看,沒輸參數的話,這貨會直接退出,連新內核的 dmesg 日誌也不會保存的)。如果 dmesg 日誌有新的警告信息,表示新發布的內核有漏網之「蟲」,這些 bug 逃過了自測和系統測試。你要看看,那些警告信息後面有沒有棧跟蹤信息?也許這裡有很多問題需要你進一步調查分析。

壓力測試

執行壓力測試的一個好辦法是同時跑三四個內核編譯任務。下載各種版本的內核,同時編譯它們,並記錄時間。比較新內核跑壓力測試和老內核跑壓力測試所花的時間,然後可以定位新內核的性能。如果新內核跑壓力測試的時間比老內核的更長,說明新內核的部分模塊性能退步了。性能問題很難調試出來。第一步是找出哪裡導致的性能退步。同時跑多個內核編譯任務對檢測內核整體性能來說是個好方法,但是這種方法涵蓋了多個內核模塊,比如內存管理、文件系統、DMA、驅動等(LCTT:也就是說,這種壓力測試沒辦法定位到是哪個模塊造成了性能的下降)。

time make all

內核測試工具

我們可以在 Linux 內核本身找到多種測試方法。下面介紹一個很好用的功能測試工具集: ktest 套件

ktest 是一個自動測試套件,它可以提供編譯安裝啟動內核一條龍測試服務,也可以跑交叉編譯測試,前提是你的系統有安裝交叉編譯所需要的軟體。ktest 依賴於 flex 和 bison。詳細信息請參考放在 tools/testing/ktest 目錄下的文檔,你可以自學成材。另外還有一些參考資料教你怎麼使用 ktest:

tools/testing/selftests 套件

我們來玩玩自測吧。內核源碼的多個子系統都有自己的自測工具,到目前為止,斷點、cpu熱插拔、efivarfs、IPC、KCMP、內存熱插拔、mqueue、網絡、powerpc、ptrace、rcutorture、定時器和虛擬機子系統都有自測工具。另外,用戶態內存的自測工具可以利用 testusercopy 模塊來測試用戶態內存到內核態的拷貝過程。下面的命令演示了如何使用這些測試工具:

編譯測試:

make -C tools/testing/selftests

測試全部:(有些測試需要 root 權限,你需要以 root 用戶登入系統然後運行命令)

make -C tools/testing/selftests run_tests

只測試單個子系統:

make -C tools/testing/selftests TARGETS=vm run_tests

tools/testing/fault-injection 套件

在 tools/testing 目錄下的另一個測試套件是 fault-injection。failcmd.sh 腳本用於檢測 slab 和內存頁分配器的錯誤。這些工具可以測試內核能否很好地從錯誤狀態中恢復回來。這些測試需要用到 root 權限。下面簡單介紹了一些當前能提供的錯誤檢測方法。隨著錯誤檢測方法的增加,這份名單也會不斷增長。最新的名單請參考 Documentation/fault-injection/fault-injection.txt 文檔。

failslab (默認選項)

產生 slab 分配錯誤。作用於 kmalloc(), kmemcachealloc() 等函數(LCTT:產生的結果是調用這些函數就會返回失敗,可以模擬程序分不到內存時是否還能穩定運行下去)。

fail_page_alloc

產生內存頁分配的錯誤。作用於 allocpages(), getfree_pages() 等函數(LCTT:同上,調用這些函數,返回錯誤)。

fail_make_request

對滿足條件(可以設置 /sys/block//make-it-fail 或 /sys/block///make-it-fail 文件)的磁碟產生 IO 錯誤,作用於 generic_make_request() 函數(LCTT:所有針對這塊磁碟的讀或寫請求都會出錯)。

fail_mmc_request

對滿足條件(可以設置 /sys/kernel/debug/mmc0/fail_mmc_request 這個 debugfs 屬性)的磁碟產生 MMC 數據錯誤。

你可以自己配置 fault-injection 套件的功能。fault-inject-debugfs 內核模塊在系統運行時會在 debugfs 文件系統下面提供一些屬性文件。你可以指定出錯的概率,指定兩個錯誤之間的時間間隔,當然本套件還能提供更多其他功能,具體請查看 Documentation/fault-injection/fault-injection.txt。 Boot 選項可以讓你的系統在 debugfs 文件系統起來之前就可以產生錯誤,下面列出幾個 boot 選項:

fault-injection 套件提供接口,以便增加新的功能。下面簡單介紹下增加新功能的步驟,詳細信息請參考上面提到過的文檔:

使用 DECLARE_FAULT_INJECTION(name) 定義默認屬性;

詳細信息可查看 fault-inject.h 中定義的 struct fault_attr 結構體。

配置 fault 屬性,新建一個 boot 選項;

這步可以使用 setup_fault_attr(attr, str) 函數完成,為了能在系統啟動的早期產生錯誤,添加一個 boot 選項這一步是必須要有的。

添加 debugfs 屬性;

使用 fault_create_debugfs_attr(name, parent, attr) 函數,為新功能添加新的 debugfs 屬性。

為模塊設置參數;

為模塊添加一些參數,對於配置錯誤屬性來說是一個好主意,特別是當新功能的應用範圍受限於單個內核模塊的時候(LCTT:不同內核,你的新功能可能需要不同的測試參數,通過設置參數,你的功能可以不必為了迎合不同內核而每次都重新編譯一遍)。

添加一個鉤子函數到錯誤測試的代碼中。

should_fail(attr, size) —— 當這個鉤子函數返回 true 時,用戶的代碼就應該產生一個錯誤。

應用程式使用這個 fault-injection 套件可以指定某個具體的內核模塊產生 slab 和內存頁分配的錯誤,這樣就可以縮小性能測試的範圍。

via: http://www.linuxjournal.com/content/linux-kernel-testing-and-debugging?page=0,2

譯者:bazz2 校對:wxy

本文由 LCTT 原創翻譯,Linux中國 榮譽推出

相關焦點

  • Linux 系統內核的調試
    在development機上將以上地址信息加入到gdb中,這樣就可以進行模塊功能的測試了。{{分頁}}3.1.2 μcLinux 2.6.x的編譯   要在SkyEye中調試作業系統內核,首先必須使被調試內核能在SkyEye所模擬的開發板上正確運行。因此,正確編譯待調試作業系統內核並配置SkyEye是進行內核調試的第一步。
  • Linux 內核的測試和調試(6)
    寫好代碼後,編譯它。把 make 過程產生的輸出保存到文檔中,查看新代碼有沒有警告信息。找到所有的警告信息,處理掉。當你的代碼編譯過程沒有任何不正常的輸出,安裝這個內核,然後啟動測試。如果啟動正常,查看 dmesg 裡面有沒於錯誤,與老內核生成的 dmesg 日誌做個比較。運行一些壓力測試,請參考我們以前講過的測試內容。如果這個補丁用於修復某個 bug,請確保真的已經修復了。
  • Linux內核調試技術之printk
    1、簡介(基於s3c2440 linux)在內核調試技術之中,最簡單的就是printk的使用了,它的用法和C語言應用程式中的
  • Linux內核常用的動態調試手段
    本文介紹lin
  • linux-3.18內核系統調用
    否則,如果某個用戶應用試圖調用這些已經被淘汰的系統調用,所得到的結果,比如打開了一個文件,就會與預期完全不同,這將令人感到非常奇怪。其實,sys_ni_syscall中的"ni"即表示"not implemented(沒有實現)"。
  • Linux 內核學習:環境搭建和內核編譯
    內核學習之一:環境搭建--安裝Debian7.3本系列文章假設讀者已對linux有一定的了解,其實學習linux內核不需要有很深的關於linux的知識,只需要了解以下內容:linux基礎知識及基本shell命令;現代作業系統的基本概念;C語言和gcc基本使用。
  • Linux 內核 TCP MSS 機制詳細分析
    [2][3] 而我在嘗試復現CVE-2019-11477漏洞的過程中,在第一步設置MSS的問題上就遇到問題了,無法達到預期效果,但是目前公開的分析文章卻沒對該部分內容進行詳細分析。所以本文將通過Linux內核源碼對TCP的MSS機制進行詳細分析。
  • 淺談Linux驅動調試利器:printk
    在實際調試中我們會發現,並不是所有的Linux內核輸出信息都可以在控制臺中顯示出來。這是因為Linux內核有對應的機制對不同級別的輸出信息進行篩選,從而只將滿足條件的信息輸出到控制臺界面。我們可以通過如下方式查詢當前控制臺的輸出等級:linux@linux-virtual-machine:~$ cat /proc/sys/kernel/printk4       4       1       7在控制臺執行指令後,會得到4個數字,分別對應以下四種情況:第1個值是控制臺的日誌級別
  • ARM Linux內核啟動要求
    arm.linux.org.uk/developer/booting.php本文引用地址:http://www.eepw.com.cn/article/201611/316973.htmAuthor: Russell KingInitial date: May 18, 2002Revision:1 - 17 September 20042
  • 「正點原子Linux連載」第三十七章Linux內核移植
    37.2.3 Linux內核啟動測試在上一小節我們已經得到了NXP官方I.MX6ULL EVK開發板對應的zImage和imx6ull-14x14-evk.dtb這兩個文件。這兩個文件能不能在正點原子的I.MX6U-ALPHA EMMC版開發板上啟動呢?
  • 使用Kdump檢查Linux內核崩潰
    加載捕獲內核的命令: # kexec -p kernel.img --initrd=initramfs-image.img –reuse-cmdline  echo c > /pros/sysrq-trigger 可用於使內核崩潰以進行測試。有關 kexec-tools 提供的選項的詳細信息,請參閱 man kexec。
  • Linux內核編譯初體驗
    下載內核在ftp://ftp.kernel.org/pub/linux/kernel/下載原版內核本文引用地址:http://www.eepw.com.cn/article/201611/319326.htm此處使用linux-2.6.22.6.tar.bz22.
  • linux內核移植-移植2.6.35.4內核到s3c2440
    本來是想移植最新的內核2.6.39但是總是在編譯快完成的時候報錯,有人說是新的內核對arm平臺的支持不好,所以就降低了一下版本,這裡移植2.6.35.4內核一、準備工作1、下載 解壓內核從官網上下載linux-2.6.35的內核, ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ ,文件不大,約85M。
  • Linux內核學習:簡單的字符設備驅動
    Linux內核設備驅動架構如下圖所示,Linux內核針對上述3類設備抽象出來一套完整的驅動框架和API接口,以便驅動開發者在編寫某類設備驅動時可重複使用。字符設備是以字節為單位的I/O傳輸,這種字符流的傳輸率通常比較低。
  • 改善Linux內核實時性方法的研究與實現
    本文詳細闡述了這些措施的原理並基於標準Linux2.6內核加以實現,最後通過測試,驗證了此改進方法的效果。  1 中斷線程化  1.1 Linux中斷對內核實時性的影響  中斷處理是由內核執行的最敏感的任務之一,當內核正打算去做一些別的事情時,中斷隨時會到來,中斷當前的任務進而執行中斷處理程序。
  • 通過一道簡單的例題了解Linux內核PWN
    / # iduid=0(root) gid=0(root) groups=1000(ctf)可以在boot.sh文件中添加-s參數來使用gdb調試,它默認埠1234。也可以指定埠號進行調試,只需要使用-gdb tcp:port即可。
  • Linux內核啟動-內核解壓縮
    本文引用地址:http://www.eepw.com.cn/article/148792.htm從內核的生成過程來看內核的連結主要有三步:第一步是把內核的原始碼編譯成.o文件,然後連結,這一步,連結的是arch/i386/kernel/head.S,生成的是vmlinux。
  • Ubuntu中升級Linux內核
    ●支持ARCv2和HS38 CPU內核  ●增加了隊列自旋鎖的支持  ●許多其他的改進和驅動更新。  在Ubuntu中如何下載4.2內核:  此內核版本的二進位包可供下載連結如下:  Download Kernel 4.2 (.DEB)  首先檢查作業系統類型,32位(i386)的或64位(amd64)的,然後使用下面方式依次下載並安裝軟體包:  1.linux-headers-4.2.0-xxx_all.deb
  • Linux內核概述
    μClinuxμClinux 是一種優秀的嵌入式 Linux 版本,其全稱為 micro-control Linux,從字面意思看是指微控制 Linux。同標準的 Linux 相比,μClinux 的內核非常小,但是它仍然繼承了 Linux 作業系統的主要特性,包括良好的穩定性和移植性、強大的網絡功能、出色的文件系統支持、標準豐富的 API,以及 TCP/IP 網絡協議等。因為沒有 MMU 內存管理單元,所以其多任務的實現需要一定技巧。
  • 深入實時 Linux
    德國嵌入式開發公司 Linutronix[3] 的 Altenberg 並不否認 Xenomai 和 RTAI 等雙核方法提供較低的延遲。然而,他揭示了新的 Linutronix 基準,旨在表明差異不如所聲稱的那樣大,特別是在實際使用中。爭議較少的是,他認為 RTL 更易於開發和維護。