【发布时间】:2012-01-05 17:48:35
【问题描述】:
我了解内核模式和用户模式的用途,以及从前者到后者的转换是如何发生的。然而,许多消息来源指出,内核模式下发生的崩溃很难调试,应该远程完成,例如通过 telnet 连接 (here is an example)。
为什么调试这么难? 为什么不能将(内核)调试器附加到其中一个内核线程并以通常的方式使用它?
【问题讨论】:
标签: operating-system computer-architecture kernel-mode
我了解内核模式和用户模式的用途,以及从前者到后者的转换是如何发生的。然而,许多消息来源指出,内核模式下发生的崩溃很难调试,应该远程完成,例如通过 telnet 连接 (here is an example)。
为什么调试这么难? 为什么不能将(内核)调试器附加到其中一个内核线程并以通常的方式使用它?
【问题讨论】:
标签: operating-system computer-architecture kernel-mode
在内核模式下崩溃可能会损坏内存中任何地方的数据结构,甚至是调试器本身。防弹是很难的。
在正常调试中,您有两个完全隔离的进程 - 调试器和您正在调试的东西。他们是“同龄人”,生而平等。被调试的进程无法触及调试器,无论它做什么(并且可能甚至不知道它存在)。另一方面,调试器可以以固定的、可预测的方式与被调试的进程交互,这些方式始终适用于所有常规用户进程。
一个例子:如果是本地调试,您将如何调试键盘接口,或者如果通过串行端口调试 RS232 代码? NIC 驱动程序或网络堆栈(如果它通过网络)?在其中一个中设置断点将无法恢复,因为您将无法访问控制调试器的设备。最坏的情况,您将如何调试内核调试器?使用 GDB,您至少在理论上可以将 GDB 实例附加到另一个 GDB 实例而不会带来太多麻烦。在内核空间中这是不可能的,因为上面没有层来调解事情。
【讨论】:
您不能以交互方式(或本地)调试内核,因为内核本身负责在监视器上显示图片(通过与适当的显示驱动程序通信),而且不仅如此。我会用另一种方式提出你的问题:调试内核是否比通过 telnet 连接更容易?
对于这个问题,我的回答是:是的。至少在 X86/X64 架构上使用虚拟化。我正在使用 VirtualBox 运行可以在本地计算机上调试的来宾操作系统。我还在使用 VirtualKD (http://virtualkd.sysprogs.org/),它极大地加快了调试机器(主机)和 VM 之间的通信。
VirtualKD 包含一个修改来宾 Windows 的 boot.ini 的包,因此您可以通过选择 Windows 显示给您的适当菜单项在启动时启用调试。
【讨论】: