kdb内核调试器

The kdb Kernel Debugger
  
  估计大家大概想知道为什么不将更多的先进调试技术集成到内核中。答案很简单,那是因为李纳斯不信任交互式的调试器。他担心它们会导致尴尬的局面,毕竟修补故障要胜于查明故障的真实原因。因此,内核没有内置的调试器。

  然而,其他的内核开发者看到了交互式调试工具的特殊用法。类似这样的工具是kdb内核内置调试器,可以从oss.sgi.com站点获得一个非正式补丁。要想使用kdb你就必须获得该补丁(确保其版本与你的内核版本相匹配),打上该补丁后,重新构建并安装内核。注意,编写本书时,kdb还只能在IA-32(x86)硬件体系下工作(曾经有过一个用于IA-64的版本,但后来被移除了)。

   一旦你有了一个支持kdb的内核,就可以通过几种方式来进入调试器。在控制台下按Pause(或Break)键可以启动调试器。当一个内核oops发生时或一个断点被触发时kdb也会启动。不管哪种是哪种情况,你都会看到一条类似下面这样的消息:


Entering kdb (0xc0347b80) on processor 0 due to Keyboard Entry






[0]kdb>



    注意当kdb运行时几乎所有关于内核的东西都会停止。在你调用kdb的系统中不应该运行其他任何程序;特别是你不应该启用网络——除非你是在调试一个网络驱动程序。如果你打算使用kdb,那么以单用户模式启动系统将会是一个好办法。  
   作为示例,我们来看一下scull的调试处理。假设驱动程序已经被加载,我们可以像下面这样用kdb在scull_read函数中设置一个断点:


[0]kdb> bp scull_read






Instruction(i) BP #0 at 0xcd087c5dc (scull_read)






is enabled globally adjust 1






[0]kdb> go



   bp命令告诉kdb停止内核对scull_read的再次调用。然后你可以输入go命令继续执行。当把数据放入一个scull设备后,我们可以在另一个终端的shell下面运行cat命令来读取它,输出如下:


Instruction(i) breakpoint #0 at 0xd087c5dc (adjusted)



0xd087c5dc scull_read: int3




Entering kdb (current=0xcf09f890, pid 1575) on processor 0 due to






Breakpoint @ 0xd087c5dc






[0]kdb>




   现在我们位于scull_read函数的开始部分。来看看我们是怎样来到这的,我们能够获得一条堆栈跟踪信息:





[0]kdb> bt




ESP EIP Function (args)



0xcdbddf74 0xd087c5dc [scull]scull_read



0xcdbddf78 0xc0150718 vfs_read+0xb8



0xcdbddfa4 0xc01509c2 sys_read+0x42



0xcdbddfc4 0xc0103fcf syscall_call+0x7




[0]kdb>




   kdb尝试输出所有函数的变量值。然而它被编译器使用的优化技巧搞糊涂了。因此,它没能正确地输出scull_read的参数。


   下面来看一些数据。mds命令能够熟练地处理数据;我们可以通过下面的命令来查看scull_devices指针的值:



[0]kdb> mds scull_devices 1






0xd0880de8 cf36ac00 ....


    这里我们请求一个起始自scull_devices的数据字(4字节);获得的答案是我们的设备数组的地址为0xd0880de8;它的第一个设备结构体位于0xcf36ac00。要查看这个设备结构,我们需要使用下面的地址:


[0]kdb> mds cf36ac00






0xcf36ac00 ce137dbc ....






0xcf36ac04 00000fa0 ....






0xcf36ac08 000003e8 ....






0xcf36ac0c 0000009b ....






0xcf36ac10 00000000 ....






0xcf36ac14 00000001 ....






0xcf36ac18 00000000 ....






0xcf36ac1c 00000001 ....



    上面的第八行对应于scull_dev结构的起始部分。因此,我们看到第一个设备的内存地址为0xce137dbc,quantum为4000(十六进制的fa0),quantum set的大小为1000(十六进制的3e8),当前有155(十六进制的9b)字节存储在该设备中。


    kdb也能够改变数据。假设我们想要整理设备中的某些数据:


[0]kdb> mm cf26ac0c 0x50






0xcf26ac0c = 0x50



   随后运行的cat命令将会返回比以前少的数据。


   kdb还有一些其他的功能,包括单步执行,在数据存储时设置断点,反汇编代码,单步调试连接列表,访问寄存器数据等等。当你安装了kdb补丁后,可以在内核源码树的Documentation/kdb目录下找到一本完整的kdb用户手册

转载于:https://www.cnblogs.com/cnchar/archive/2006/10/11/526708.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值