2011-05-06 73 views
9

爲了測試內核在泄漏內存時的行爲,我正在編寫一個內核模塊,用於連續分配內存。代碼看起來像如何確定Linux內核模塊是否泄漏內存

int bytesLeaked = 128000; 
char *var = kmalloc(bytesLeaked, GFP_KERNEL); 
if (var != NULL) 
printk("leaked %d bytes at address %x\n", bytesLeaked, (unsigned int)var); 

此代碼位於init_module中。我有以下問題

  1. 如何確定代碼是否泄漏了內存? lsmod並沒有透露太多。
  2. 互聯網上的教程只顯示init_module和exit_module中的代碼。如果我希望在插入模塊之後但退出之前的一段時間內完成內存分配。
  3. 我是否可以編寫泄漏內存的代碼,只有當用戶給出指令時纔會這樣做,例如,用戶空間程序是否可以執行系統調用,從而導致模塊泄漏內存?當它分配的內存塊(諸如與kmalloc()),然後輸給該存儲器塊的所有參考文獻而沒有第一釋放它

回答

0
  1. 代碼泄漏內存。你的代碼沒有這樣做,因爲你仍然有var的範圍,並指向你的內存塊。如果你在下一行添加var = NULL;,那麼你有一個真正的內存泄漏。

  2. 而且它是絕對有可能的,以便用戶空間中的事件觸發你的內核模塊開始分配內存。我不確定您是否可以通過系統調用直接執行此操作,但是如果您不能,那麼還有其他方法可以完成此任務。你只需要選擇一個並實施它。即使每次想要觸發內存分配時都要有一個預定文件,您可以使用touch。雖然我不明白爲什麼你不能讓你的init_module代碼產生一個只是隨着時間的推移定期分配內存的線程,如果這是你想要的行爲。

+4

re 1:內存泄漏的定義屬性是從不釋放分配,不一定沒有對它的引用。另外,'var'可能會在某個時間點超出範圍,屆時您的引用計數將變爲0。 (讓我們忽略「參考」在C語言中沒有明確定義的事實。) – Karmastan 2011-05-06 19:18:30

+0

謝謝。我試圖編寫線程的產卵,但代碼非常複雜http://www.scs.ch/~frey/linux/kernelthreads.html。你能否提供一個關於如何在沒有系統調用的情況下通過用戶空間事件觸發內存分配的見解。 – kakinada 2011-05-09 07:08:26

+0

KEDR支持2.6.31或更新的內核版本。礦是2.6.28。看起來像KEDR不能使用。我會嘗試找到類似的內核工具,我有 – kakinada 2011-05-09 07:24:07

18

如果需要檢查,如果一個內核模塊已經泄漏的內存和你的機器有x86架構,您可以使用KEDR system,它包括內存泄漏檢測。

KEDR不要求您重建內核。在線文檔(例如,參見「入門」)介紹瞭如何安裝和使用KEDR。總之,程序如下。

安裝(從源):解壓源存檔 - cmake的< ...> - 讓 - 使安裝

開始KEDR你加載模塊:

$ kedr start <name_of_the_module_to_analyze> -f leak_check.conf 

然後你就可以加載模塊並像往常一樣使用它。當你卸載它,KEDR會給你debugfs報告(通常debugfs安裝/sys/kernel/debug),例如:關於每個泄露

$ cat /sys/kernel/debug/kedr_leak_check/info 
Target module: "...", 
Memory allocations: 3 
Possible leaks: 2 
Unallocated frees: 0 

文件possible_leaks/sys/kernel/debug/kedr_leak_check/提供的信息(地址,大小,調用堆棧)內存塊。

最後,你可以停止KEDR(注意/sys/kernel/debug/kedr_leak_check/將消失):

kedr stop 

如果您使用的是帶有x86之外架構的系統,Kmemleak也可能是有幫助的,雖然它是比較難一點使用。您可能需要使用CONFIG_DEBUG_KMEMLEAK參數設置爲'y'來重建內核。儘管如此,Kmemleak也是一個非常有用的工具。有關詳細信息,請參閱內核源代碼中的Documentation/kmemleak.txt

+2

KEDR支持2.6.31或更新的內核版本。礦是2.6.28。看起來像KEDR不能使用。我將嘗試爲我的內核找到類似的工具 – kakinada 2011-05-09 07:27:27