加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux kdb 内核调试器

发布时间:2020-12-13 23:13:26 所属栏目:Linux 来源:网络整理
导读:许多读者可能奇怪为什么内核没有建立更多高级的调试特性在里面.答案,非常简单,是 Linus 不相信交互式的调试器. 他担心它们会导致不好的修改,这些修改给问题打了补丁 而不是找到问题的真正原因. 因此,没有内嵌的调试器. ? 其他内核开发者,但是,见到了交互式调

许多读者可能奇怪为什么内核没有建立更多高级的调试特性在里面.答案,非常简单,是 Linus 不相信交互式的调试器. 他担心它们会导致不好的修改,这些修改给问题打了补丁 而不是找到问题的真正原因. 因此,没有内嵌的调试器.

?

其他内核开发者,但是,见到了交互式调试工具的一个临时使用. 一个这样的工具是 kdb 内嵌式内核调试器,作为来自 oss.sgi.com 的一个非官方补丁. 要使用 kdb,你必须获 得这个补丁(确认获得一个匹配你的内核版本的版本),应用它,重建并重安装内核. 注意,直到本书编写时,kdb 只在 IA-32(x86)系统中运行(尽管一个给 IA-64 的版本在主线内核 版本存在了一阵子,在被去除之前.)

?

一旦你运行一个使能了 kdb 的内核,有几个方法进入调试器. 在控制台上按下 Pause(或 者 Break) 键启动调试器. kdb 在一个内核 oops 发生时或者命中一个断点时也启动,在 任何一种情况下,你看到象这样的一个消息:

?

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

?

注意,在 kdb 运行时内核停止任何东西. 在你调用 kdb 的系统中不应当运行其他东西; 特别,你不应当打开网络 -- 除非,当然,你在调试一个网络驱动. 一般地以单用户模式 启动系统是一个好主意,如果你将使用 kdb.

?

作为一个例子,考虑一个快速 scull 调试会话. 假设驱动已经加载,我们可以这样告诉 kdb 在 sucll_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 设备后,我们可以试着通过在另一个终端的外壳下运行 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 命令操作数据; 我们可以查询 schull_devices 指针的值,使用这样一个命令:

?

[0]kdb> mds scull_devices 1 0xd0880de8 cf36ac00 ....

?

这里我们要求一个(4 字节)字,起始于 scull_devices 的位置; 答案告诉我们的设备数组 在地址 0xd0880de8; 第一个设备结构自己在 0xcf36ac00. 为查看那个设备结构,我们需 要使用这个地址:

?

[0]kdb> mds cf36ac00 0xcf36ac00 ce137dbc .... 0xcf36ac04 00000fa0 .... 0xcf36ac08 000003e8 ....

0xcf36ac0c 0000009b .... 0xcf36ac10 00000000 ....

0xcf36ac14 00000001 ....

0xcf36ac18 00000000 ....

0xcf36ac1c 00000001 ....

?

这里的 8 行对应于 scull_dev 结构的开始部分. 因此,我们看到第一个设备的内存位于 0xce137dbc,quantum 是 4000 (16 进制 fa0),量子集大小是 1000 (16 进制 3e8 ),当 前有 155( 16 进制 9b) 字节存于设备中.

kdb 也可以改变数据. 假想我们要截短一些数据从设备中: [0]kdb> mm cf26ac0c 0x50

0xcf26ac0c = 0x50

?

在设备上一个后续的 cat 会返回比之前少的数据.

?

kdb 有不少其他功能,包括单步(指令,不是 C 源码的一行),在数据存取上设置断点,反汇编代码,步入链表,存取寄存器数据,还有更多. 在你应用了 kdb 补丁后,一个完 整的手册页集能够在你的源码树的 documentation/kdb 下发现.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读