第十八章調試linux
18.1 準備開始app
須要準備的東西:ide
l 一個bug:大部分bug一般都不是行爲可靠並且定義明確的函數
l 一個藏匿bug的內核版本:找出bug首先出現的版本工具
l 相關內核代碼的知識和運氣oop
最好能讓bug重現,有一些bug存在並且有人沒辦法讓他重現,由於內核與用戶程序和硬件間的交互很微妙。測試
18.2內核中的bugdebug
能夠有無數種緣由產生,表象也變化無窮。代碼中的錯誤每每引起一系列連鎖反應,目睹者纔看到bug。調試
18.3經過打印來調試日誌
內核提供了打印函數printk()。和C庫中的printf()幾乎相同。
Printk()的特質:
l 健壯性:任什麼時候候,任何地方均可以調用。僅有的不能調用的狀況是在終端還沒初始化以前。Early_printk()再啓動過程初期就能夠打印。
l 日誌等級:能夠在打印的消息的開頭加上記錄等級,內核經過記錄等級和當前終端的記錄登記比較,來決定是否打印。最好給消息加記錄等級 ,否則就是默認等級KERN_WARNING。<0>到<7>。
l 記錄緩衝區:內核消息保存在一個環形隊列中,單處理器默認16k,環形能夠新信息覆蓋老信息。好處是同步問題容易解決,記錄也容易維護。壞處是可能會丟失信息。
l Syslogd和klogd:用戶空間的守護進程klogd從記錄緩衝區中獲取內核消息,再經過syslogd守護進程將它們保存在系統日誌。
l Printf()到printk():等啥時候寫C語言會把pringf()錯寫成printk()就好了。
18.4opps
Oops:是內核告知用戶有不幸發生的最經常使用方式。由於內核不能自我修復,也不能將本身殺死,因此只有發oops。一般發完oops,內核會處於不穩定狀態。內核必須適當的從當前上下文環境退出並嘗試恢復對系統的控制,但通常會死機。寄存器上下文和回溯線索。
l Ksymoops:解析opps信息。Ksymoops save_oops.txt
l Kallsyms:解碼不須要再使用system.map和ksymoops工具了
18.5 內核調試配置選項
爲了方便調試和測試內核代碼,內核提供了配置選項。能夠啓用slab layer debugging,high-memory debugging,I/O mapping debugging,spin-lock debugging,stack-overflow checking.其中最有用的是sleep-inside-spinlock check
.
18.6引起bug並打印信息
一些內核調用能夠用來方便標記bug,BUG(),BUG_ON()
Panic()能夠引起更嚴重的錯誤。dumo_stack()僅在終端上打印寄存器上下文和跟蹤線索。
18.7神奇的系統請求鍵
Sysrq(系統請求)鍵是救命稻草,不管內核出於什麼狀態,均可以和內核進行通訊。
Sysrq-h:獲取一份可用選項列表
Sysrq-s:將髒緩衝區跟硬盤交換分區同步
Sysrq-u:卸載全部的文件系統
Sysrq-b:重啓設備
18.8內核調試器的傳奇
Gdb:gdb vmlinux /proc/kcore啓動調試器。Gdb不能修改內核數據,不能設斷點。
Kgdb:一個補丁,讓咱們在遠端主機上經過串口利用gdb的全部功能得內核進行調試。
18.9探測系統
用UID做爲選擇條件
使用條件變量
使用統計量
重複頻率限制
18.10用二分法找出引起罪惡的變動
知道bug是什麼版中出現的,就能夠對比沒有bug的版本,找出引起bug的代碼變動。用二分法找到兩個相繼版本,一個有bug,一個沒bug
18.11使用Git進行二分搜索
Git源碼管理工具提供二分搜索機制