kernel module编程(九):通过用户程序的strace检查内核模块调用情况

  本文也即《Linux Device Drivers》,LDD3的第四章Debuging Techniques的读书笔记之四,但我们不限于此内容。

  由于最近比较忙,赶文档,这么多天没看两页纸。前两天来个老外,forgive my poor English。和他到我们饭堂吃饭,还有几个同事坐在一起,一同六个人,5个人拿匙羹,一个人用筷子,用筷子的人是老外……

  在前面我们学习了两种通过/proc的方法来获取device或者查看kernel module的信息。还可以通过IOCTL的方式通过file descriptor来进行操作。这种方式可以直接获取信息,可用二进制的方式,而不是向/proc的文本方式,每次获取的容量不受page大小限制。另外不需要生成一个/proc的文件,这个文件是所有用户可视。这种方式的唯一缺点就是必须另外编写ioctl文件来进行读取,并且会复杂一些。我记得我以前一个网络数据分析就是使用这种方式,在kernel module中通过关键字匹配方式过滤数据包,用户程序通过ioctl来不断获取,协议分析在用户程序中实现。我翻了一下目录,ioctl在第六章介绍。

  对于小的问题,我们可以使用strace来跟踪用户程序,实际用来检查我们的内核模块程序。strace跟踪kernel的system call。strace的具体使用方式可通过man获得。例如-t显示调用system call的时间,-T表示执行system call的时间。在读写操作方面,会显示buffer的部分内容,每次希望以及实际读写的大小。在scull中我们写了一个例子程序test,用于对/dev/scull0进行写读操作,见kernel module编程(五):设备读写 。由于strace可以携带参数,而我们运行的程序也可以携带参数,因此请注意写法。

$ strace –t ./test

  下面是部分显示的内容:倒数第三行,表示试图写1500字节,实际写了1024字节。

open("/dev/scull0", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(1, "device scull0 is open , fd = 1644"..., 39device scull0 is open , fd = 164497944 ) = 39
fstat64(3, {st_mode=S_IFCHR|0664, st_rdev=makedev(248, 0), ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfdb69e4) = -1 ENOTTY (Inappropriate ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fb8000
write(1, "write = 1500/n"..., 13write = 1500 )       = 13
write(3, "#################################"..., 1500) = 1024
write(3, "*********************************"..., 476) = 476
close(3)                                = 0

  我将例子程序中读的最后fclose(file)改为close(file),在我们执行test的时候不会报告错误,但是通过strace,我们发现:

read(3, ""..., 4096)                    = 0
close(164497944)                        = -1 EBADF (Bad file descriptor)
exit_group(0)                           = ?

  出现异常,因此检查我们的程序,修订为fclose。strace能够显示调用函数的参数,包括一些buffer值,还可以通过来显示执行时间等,是个不错的工具。(^_^,以前没用过,浪费啊)

相关链接:我的与kernel module有关的文章

你可能感兴趣的:(读书笔记,程序设计,嵌入式Linux)