linux 核心調試技術__linux

來源:互聯網
上載者:User

  linux 調試

目錄[-] 一  調試前的準備 二  核心中的bug 三  核心調試配置選項 1  核心配置 2  調試原子操作 四  引發bug並列印資訊 1  BUG()和BUG_ON() 2  dump_stack() 五  printk() 1  printk函數的健壯性 2  printk函數脆弱之處 3  LOG等級 4  記錄緩衝區 5  syslogd/klogd 6  dmesg 7 注意  8 核心printk和日誌系統的總體結構 9  動態調試 六  記憶體調試工具 1  MEMWATCH 2  YAMD 3  Electric Fence 七  strace 八  OOPS 1  ksymoops 2  kallsyms 3  Kdump 九  KGDB 1  kgdb的調試原理 2  Kgdb的安裝與設定 3  在VMware中搭建調試環境 4  kgdb的一些特點和不足 十  使用SkyEye構建Linux核心調試環境 1  SkyEye的安裝和μcLinux核心編譯 2  使用SkyEye調試 3  使用SkyEye調試核心的特點和不足 十一  KDB 1  入門 2  初始化並設定環境變數 3  啟用 KDB 4  KDB 命令 5  技巧和訣竅 6  結束語 十二  Kprobes 1  安裝 2  編寫 Kprobes 模組 3  使用 Kprobes 更好地進行調試 核心開發比使用者空間開發更難的一個因素就是核心調試艱難。核心錯誤往往會導致系統宕機,很難保留出錯時的現場。調試核心的關鍵在於你的對核心的深刻理解。

一  調試前的準備 在調試一個bug之前,我們所要做的準備工作有:
有一個被確認的bug。 包含這個bug的核心版本號碼,需要分析出這個bug在哪一個版本被引入,這個對於解決問題有極大的協助。可以採用二分尋找法來逐步鎖定bug引入版本號碼。 對核心代碼理解越深刻越好,同時還需要一點點運氣。 該bug可以複現。如果能夠找到複現規律,那麼離找到問題的原因就不遠了。 最小化系統。把可能產生bug的因素逐一排除掉。
二  核心中的bug 核心中的bug也是多種多樣的。它們的產生有無數的原因,同時表象也變化多端。從隱藏在原始碼中的錯誤到展現在目擊者面前的bug,其發作往往是一系列連鎖反應的事件才可能出發的。雖然核心調試有一定的困難,但是通過你的努力和理解,說不定你會喜歡上這樣的挑戰。

三  核心調試配置選項 學習編寫驅動程式要構建安裝自己的核心(標準主線核心)。最重要的原因之一是:核心開發人員已經建立了多項用於調試的功能。但是由於這些功能會造成額外的輸出,並導致能下降,因此發行版廠商通常會禁止發行版核心中的調試功能。

1  核心配置

為了實現核心調試,在核心配置上增加了幾項: view source print ?

01 Kernel hacking  --->      
02 [*]   Magic SysRq key 
03 [*]   Kernel debugging 
04 [*]   Debug slab memory allocations   
05 [*]   Spinlock and rw-lock debugging: basic checks 
06 [*]   Spinlock debugging: sleep-inside-spinlock checking 
07            [*]   Compile the kernel with debug info   
08 Device Drivers  --->   
09            Generic Driver Options  ---> 
10            [*]   Driver Core verbose debug messages 
11 General setup  ---> 
12            [*]   Configure standard kernel features (for small systems)  ---> 
13            [*]   Load all symbols for debugging/ksymoops
啟用選項例如:
view source print ?
1 slab layer debugging(slab層調試選項) 
2 high-memory debugging(高端記憶體調試選項) 
3 I/O mapping debugging(I/O映射調試選項) 
4 spin-lock debugging(自旋鎖調試選項) 
5 stack-overflow checking(棧溢出檢查選項) 
6 sleep-inside-spinlock checking(自旋鎖內睡眠選項)

2  調試原子操作 從核心2.5開發,為了檢查各類由原子操作引發的問題,核心提供了極佳的工具。
核心提供了一個原子操作計數器,它可以配置成,一旦在原子操作過程中,進城進入睡眠或者做了一些可能引起睡眠的操作,就列印警告資訊並提供追蹤線索。
所以,包括在使用鎖的時候調用schedule(),正使用鎖的時候以阻塞方式請求分配記憶體等,各種潛在的bug都能夠被探測到。
下面這些選項可以最大限度地利用該特性:
view source print ?
1 CONFIG_PREEMPT = y 
2 CONFIG_DEBUG_KERNEL = y 
3 CONFIG_KLLSYMS = y 
4 CONFIG_SPINLOCK_SLEEP = y

四  引發bug並列印資訊 1  BUG()和BUG_ON()

一些核心調用可以用來方便標記bug,提供斷言並輸出資訊。最常用的兩個是BUG()和BUG_ON()。

定義在<include/asm-generic>中:

view source print ?

01 #ifndef HAVE_ARCH_BUG 
02 #define BUG() do { 
03    printk("BUG: failure at %s:%d/%s()! ", __FILE__, __LINE__, __FUNCTION__); 
04    panic("BUG!");   /* 引發更嚴重的錯誤,不但列印錯誤訊息,而且整個系統業會掛起 */ 
05 } while (0) 
06 #endif 
07   
08 #ifndef HAVE_ARCH_BUG_ON 
09    #define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0) 
10 #endif
當調用這兩個宏的時候,它們會引發OOPS,導致棧的回溯和錯誤訊息的列印。
※ 可以把這兩個調用當作斷言使用,如:BUG_ON(bad_thing);

2  dump_stack() 有些時候,只需要在終端上列印一下棧的回溯資訊來協助你調試。這時可以使用dump_stack()。這個函數只在終端上列印寄存器上下文和函數的跟蹤線索。
view source print ?
1 if (!debug_check) { 
2     printk(KERN_DEBUG “provide some information…/n”); 
3     dump_stack(); 
4 }


五  printk() 核心提供的格式化列印函數。
1  printk函數的健壯性       健壯性是printk最容易被接受的一個特質,幾乎在任何地方,任何時候核心都可以調用它(中斷上下文、進程上下文、持有鎖時、多處理器處理時等)。


2  printk函數脆弱之處       在系統啟動過程中,終端初始化之前,在某些地方是不能調用的。如果真的需要調試系統啟動過程最開始的地方,有以下方法可以使用:
使用串口調試,將調試資訊輸出到其他終端裝置。 使用early_printk(),該函數在系統啟動初期就有列印能力。但它只支援部分硬體體系。



3  LOG等級        printk和printf一個主要的區別就是前者可以指定一個LOG等級。核心根據

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.