【zz】linux内核驱动模块的调试技术总结

【zz】linux内核驱动模块的调试技术总结

原文: http://www.cnitblog.com/textbox/articles/61881.html

这些天来弄了一个简单的驱动模块,后发现系统只要一卸载模块系统就会死掉。到底是那里出了错?
如果你只是通过printk来调试, 而没有其他的方法去检测错误的。
也是这个原因促使我写驱动模块调试技术相关技术。要学好一个编程语言工具首先调试技术也一定同步。
(如果linux 也能做出一个类似windows 下的 Windbg 或 Soft-ICE 那就不必那么麻烦了)
这篇文章不是一气呵成的,只是我在学习内核调试的一个笔记。

调试技术有以下几种:

  1.用打印调试
  2.文件保存调试信息
  3.truss、strace和ltrace命令输出信息来调试
  4.调试器来调试

对于第一种 “用打印调试 ”
利用函数或命令把相应的信息输出到console或文件内
这些函数有 printk , STOCLINUX 等等

prink 的一般用法是定义成一个公用的宏

#undef  PDEBUG             /* undef it, just in case */
#ifdef SCULL_DEBUG
   #ifdef __KERNEL__
     
/*  This one if debugging is on, and kernel space  */
       #define PDEBUG(fmt, args) printk( KERN_DEBUG 
" scull:  "  fmt, ## args)
   #
else
     
/*  This one for user space  */
       #define PDEBUG(fmt, args) fprintf(stderr, fmt, ## args)
   #endif
#else
   #define PDEBUG(fmt, args
/*  not debugging: nothing  */
#endif

#undef  PDEBUGG
#define  PDEBUGG(fmt, args) /* nothing: it's a placeholder */
在makefile 里面添加
 
DEBUG  =  y
# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
DEBFLAGS 
=   - - - D SCULL_DEBUG #  " -O "   is  needed to expand inlines
else
DEBFLAGS 
=   - O2
endif
CFLAGS 
+=  $(DEBFLAGS)

这样定义的宏可以在内核模式和用户模式在 Debug 版本下输出调试信息,而在release版本编译时候去掉调试输出的函数代码。
并可以通过设置makefile就可以是否输出调试信息, 缺点是修改makefile还需要重新编译一次
想法,如果能给模块一个配置文件 (*.conf)那就修改配置文件就不用重新编译,只需要卸载安装模块就实现调试信息的输出,
缺点是影响系统的性能。


对於第二种 “文件保存调试信息 ”
内核模式下可以使用 /proc文件系统 或者 seq_file 来记录调试信息。创建自己的/proc文件系统的文件 或 seq_file 文件 并记录相应的调试信息,用于查询。
seq_file 操作可以参考 http://blog.chinaunix.net/u/12313/showart_172686.html;


还有 用ioctl 命令。这些命令可以从驱动模块拷贝相关的数据结构到用户空间, 用于查询它们,缺点是需要用另外的程序来发出和显示调试信息,并增加模块的体积 。优点是比/proc块

oops消息 ,通常消息发生于引用了 NULL 指针或者使用其他不正确指针值。


调试器

 使用 gdb
   优点:比较适用于用户模式下调试程序,linux自带无需重新安装
   缺点:不适合内核模块的调试(也可以内核调试,利用它的远程调试功能。需要两台电脑)
 
  主要步骤是
  1.执行  #gdb program
  2.执行到mian():#start
  3.设置断点
  4.调试

 具体命令使用:  参考 http://baike.baidu.com/view/639266.htm



 使用kdb
 优点:不需要远程调试
 缺点:不支持源代码级别上的调试只能使用汇编级别的调试,需要重新下载安装包,安装需要重新编译内核激活kdb


 使用 kgdb
 优点:可以对内核进行全方面的调试  (感觉有点类似 windows 下的WinDdg)
 缺点:需要两台电脑,配置复杂 ,更新慢,到目前位置最高只能支持2.6.15.5 版本的内核


 使用Linux Trace Toolkit



 使用Dynamic Probes ( DProbes )

 
使用 SkyEye
 优点: ARM Simulator很好地结合在了一起 主要用于嵌入式驱动开发领域
 缺点:配置文件设置复杂

使用 UML (虚拟机类似)
优点: UML适合于调试那些处理与硬件无关的驱动程序
缺点: UML并不适合于调试那些处理实际硬件的驱动程序

使用 JTAG- based debuggers
优点: The JTAG (Joint Test Action Group) based debuggers are hardware assisted and powerful tools
缺点: but are expensive.

你可能感兴趣的:(【zz】linux内核驱动模块的调试技术总结)