2012-02-04 72 views
1

我正在嘗試調試顯然會導致其他 任務掛起的設備驅動程序。確定性是哪個任務或哪個時間會掛起。內核調試掛起進程?

基本上我從內核收到一些錯誤消息,說「任務有 被阻塞超過120秒」,以及一些堆棧跟蹤。 掛起的任務從sendmail的變化到MKFS到將pdflush(內核線程」。 而在堆棧跟蹤中最頂端的功能從改變‘getnstimeofday’ 爲‘bio_submit’到‘mark_locks_held’。

我有一個硬因爲很難找到 問題,內核提供的堆棧跟蹤對 沒有太大幫助。根據這些堆棧跟蹤,一些掛起進程 甚至沒有試圖抓住一個鎖(就像在我不知道爲什麼他們掛起。

所以我想知道如果有人有一些想法如何調試這樣一個 問題。 kgdb是否會在這裏有用,或許通過給我提供什麼 點過程掛起,以及它正在等待什麼樣的鎖?

任何建議表示讚賞。

+0

你的內核編譯爲使用幀指針嗎? – Karmastan 2012-02-04 18:38:49

+0

不,不是。它確實有所有的調試選項。 – yangsuli 2012-02-04 18:51:33

回答

0

如果在內核中沒有啓用幀指針,堆棧跟蹤將不可靠,並且令您感到困惑。內核要求掃描整個堆棧以獲取可能是指向內核代碼的指針(即潛在的返回地址)的值。這意味着過去已經返回的函數調用可能仍然會被打印。

如果您有代碼是這樣的:

void A(void) { 
    printk("foo\n"); 
} 

void B(void) { 
    int x; 
    A(); 
} 

void crash(void) { 
    char buf[32]; 
    *(int*)0 = 0; 
} 

void trouble(void) { 
    int x; 
    B(); 
    crash(); 
} 

你的堆棧轉儲可能會出現這樣的:

printk 
A 
crash 
foo 
trouble 
... 

至於如何調試您的問題,我有兩個建議:

  1. 由於知道某些調試輸出錯誤,請使用您自己的代碼知識來弄清楚real調用堆棧。這可能有助於在多個堆棧轉儲中查找常用功能。

  2. 重新編譯內核以使用幀指針。

內核仍會打印每個看起來像返回地址的值,但會用「?」標記不可靠的地址。所以你的堆棧轉儲可能看起來像這樣:

? printk 
? A 
crash 
? foo 
trouble 
+0

所以我繼續重新編譯我的內核幀指針。堆棧跟蹤似乎還不是很可靠... 例如,我得到一個堆棧跟蹤說: ]? mutex_lock_nested + 0x13c/0x224 [] mutex_lock_nested + 0x143/0x224 []?real_lookup + 0x24/0xc5 [] real_lookup + 0x24/0xc5 這是非常可疑的,因爲我沒有看到real_lookup在源代碼中調用mutex_lock_nested! (我正在使用2.6.26) – yangsuli 2012-02-04 22:43:24

+0

我更新了我的帖子以解決您的評論。 – Karmastan 2012-02-06 18:35:21

+0

@yangsuli:你可能也想看看[這裏](http://lxr.linux.no/#linux+v2.6.26/fs/namei.c#L505)和[here](http:// lxr。 linux.no/#linux+v2.6.26/include/linux/mutex.h#L131)。 – Karmastan 2012-02-06 18:39:04