Kprobe在Linux kernel debug中的應用

原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://alanwu.blog.51cto.com/3652632/1109054

 

一直在做kernel開發方面的工作,也一直苦於kernel debug的困惑,到底如何進行kernel開發的debug的工作?今天經美國同事的推薦,我認爲kprobe是一個非常好的debug工具。其本質原理就是在你需要probe的地方放入斷點指令,然後在斷點處調用你的調試/測試程序,從而可以實現對kernel程序的調試/測試。
 
Kprobe只是提供了一種機制,使得用戶可以在系統運行時調試/測試內核程序。使用Kprobe需要做如下幾件事情:
 
1,需要找到測試點所對應的內存地址。這件工作可能是最麻煩的,如果測試點是函數,那麼可以通過/proc/kallsyms接口得到需要測試函數的內存地址,當然也可以通過kallsyms_lookup_name函數找到函數的內存地址。如果測試點是函數中間的某個位置,那麼需要通過通過反彙編找到這個內存地址,這一步可以通過objdump來完成。目前,我不知道是不是有現成的程序可以完成測試點內存地址的查找工作,我覺得完全可以開發一個perl腳本對ko文件解析,從而獲取測試點的內存地址。
 
2,寫一個kernel module,完成信息收集,測試等工作,所有的測試代碼需要在這個kernel module中完成。
 
下面是我今天的一個測試程序,用Kprobe測試一個內核函數所用的jiffies時間,基本上是一個Kprobe kernel module的基本框架,僅供參考:

 

  1. /*  
  2.  * kprobe_jiffies.c  
  3.  */  
  4.  
  5. #include <linux/module.h> 
  6. #include <linux/kernel.h> 
  7. #include <linux/string.h> 
  8. #include <linux/init.h> 
  9. #include <linux/kprobes.h> 
  10. #include <linux/kallsyms.h> 
  11.  
  12. /* global probe object */  
  13. struct kprobe probe;  
  14.  
  15. /* jiffies record */  
  16. unsigned long jiffies_enter = 0;  
  17. unsigned long jiffies_exit = 0;  
  18.  
  19. /*  
  20.  * enter the probe pointer  
  21.  */  
  22. static int pre_probe(struct kprobe *probe, struct pt_regs *regs)  
  23. {  
  24.     jiffiesjiffies_enter = jiffies;  
  25.     return 0;  
  26. }  
  27.  
  28. /*  
  29.  * exit the probe pointer  
  30.  */  
  31. static void post_probe(struct kprobe *probe, struct pt_regs *regs, unsigned long flags)  
  32. {  
  33.     unsigned long diff;  
  34.  
  35.     jiffiesjiffies_exit = jiffies;  
  36.     diff = jiffies_exit - jiffies_enter;  
  37.     printk("spending time: %lu, enter: %lu, exit: %lu\n",  
  38.             diff, jiffies_enter, jiffies_exit);  
  39. }  
  40.  
  41. static int __init kprobe_jiffies_init(void)  
  42. {  
  43.     probe.pre_handler = pre_probe;  
  44.     probe.post_handler = post_probe;  
  45.  
  46.     probe.addr = (kprobe_opcode_t *) kallsyms_lookup_name("probe_function");  
  47.     if (probe.addr == NULL) {  
  48.         printk("Cannot find out 'dd_xor_encode_sse' in system\n");  
  49.         return 1;  
  50.     }  
  51.  
  52.     register_kprobe(&probe);  
  53.     printk("register probe jffies driver.\n");  
  54.     return 0;  
  55. }  
  56.  
  57. static void __exit kprobe_jiffies_exit(void)  
  58. {  
  59.     unregister_kprobe(&probe);  
  60.     printk("unregister probe jffies driver.\n");  
  61.     return;  
  62. }  
  63.  
  64. module_init(kprobe_jiffies_init);  
  65. module_exit(kprobe_jiffies_exit);  
  66.  
  67. MODULE_AUTHOR("xxx");  
  68. MODULE_DESCRIPTION("kernel probe driver");  
  69. MODULE_LICENSE("GPL");  

 

 

我想Kprobe是個非常不錯的東西,如果在Kprobe的基礎上包裝一下,使得用戶更加容易的使用,那麼對內核程序的調試將是會發生革命性的變化。我想有時間我應該在Kprobe的基礎上做一個內核調試工具了。

本文出自 “存儲之道” 博客,請務必保留此出處http://alanwu.blog.51cto.com/3652632/1109054

發佈了1 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章