Linux设备驱动调试技术 2

本文介绍了Linux设备驱动调试中的两种方法:通过监视调试和处理系统故障。利用strace工具可以观察用户空间程序的行为,检查驱动程序响应是否正常。strace能够显示系统调用和参数,有助于诊断问题。在系统故障时,驱动程序可能导致进程崩溃,但不会使整个系统瘫痪。错误信息通常以oops消息形式出现,可以使用klogd或ksymoops工具进行解码,以确定错误来源。klogd在系统启动时加载符号表,ksymoops则提供更详细的符号信息和代码转储,帮助开发者定位问题。
摘要由CSDN通过智能技术生成

4.3  通过监视调试 
有时,通过监视用户空间中应用程序的运行情况,可以捕捉到一些小问题。监视程序同样也有助于确认驱动程序工作是否正常。例如,看到 scull 的 read 实现如何响应不同数据量的 read 请求后,我们就可以判断它是否工作正常。

有许多方法可监视用户空间程序的工作情况。可以用调试器一步步跟踪它的函数,插入打印语句,或者在 strace 状态下运行程序。在检查内核代码时,最后一项技术最值得关注,我们将在此对它进行讨论。

strace 命令是一个功能非常强大的工具,它可以显示程序所调用的所有系统调用。它不仅可以显示调用,而且还能显示调用参数,以及用符号方式表示的返回值。当系统调用失败时,错误的符号值(如 ENOMEM)和对应的字符串(如Out of memory)都能被显示出来。strace 有许多命令行选项;最为有用的是 -t,用来显示调用发生的时间;-T,显示调用所花费的时间; -e,限定被跟踪的调用类型;-o,将输出重定向到一个文件中。默认情况下,strace将跟踪信息打印到 stderr 上。

strace从内核中接收信息。这意味着一个程序无论是否按调试方式编译(用 gcc 的 -g选项)或是被去掉了符号信息都可以被跟踪。与调试器可以连接到一个运行进程并控制它一样,strace 也可以跟踪一个正在运行的进程。

跟踪信息通常用于生成错误报告,然后发给应用开发人员,但是它对内核编程人员来说也同样非常有用。我们已经看到驱动程序是如何通过响应系统调用得到执行的;strace 允许我们检查每次调用中输入和输出数据的一致性。

例如,下面的屏幕信息显示了 strace ls /dev > /dev/scull0 命令的最后几行:


[...] 
open("/dev", O_RDONLY|O_NONBLOCK)     = 4 
fcntl(4, F_SETFD, FD_CLOEXEC)         = 0 
brk(0x8055000)                        = 0x8055000 
lseek(4, 0, SEEK_CUR)                 = 0 
getdents(4, , 3933)   = 1260 
[...] 
getdents(4, , 3933)    = 0 
close(4)                              = 0 
fstat(1, {st_mode=S_IFCHR|0664, st_rdev=makedev(253, 0), ...}) = 0 
ioctl(1, TCGETS, 0xbffffa5c)          = -1 ENOTTY (Inappropriate ioctl 
                                                   for device) 
write(1, "MAKEDEV\natibm\naudio\naudio1\na"..., 4096) = 4000 
write(1, "d2\nsdd3\nsdd4\nsdd5\nsdd6\nsdd7"..., 96) = 96 
write(1, "4\nsde5\nsde6\nsde7\nsde8\nsde9\n"..., 3325) = 3325 
close(1)                              = 0 
_exit(0)                              = ?

 


很明显,ls 完成对目标目录的检索后,在首次对 write 的调用中,它试图写入 4KB 数据。很奇怪(对于 ls 来说),实际只写了4000个字节,接着它重试这一操作。然而,我们知道scull的 write 实现每次最多只写一个量子(scull 中设置的量子大小为4000个字节),所以我们所预期的就是这样的部分写入。经过几个步骤之后,每件工作都顺利通过,程序正常退出。

另一个例子,让我们来对 scull 设备进行读操作(使用 wc 命令):


[...] 
open("/dev/scull0", O_RDONLY)           = 4 
fstat(4, {st_mode=S_IFCHR|0664, st_rdev=makedev(253, 0), ...}) = 0 
read(4, "MAKEDEV\natibm\naudio\naudio1\na"..., 16384) = 4000 
read(4, "d2\nsdd3\nsdd4\nsdd5\nsdd6\nsdd7"..., 16384) = 3421 
read(4, "", 16384)                      = 0 
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(3, 7), ...}) = 0 
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 
write(1, "   7421 /d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值