我正在阅读有关操作系统的一些常规内容并触及了一个问题。开发人员在开发操作系统时如何调试,即调试操作系统本身?可以为OS开发人员调试哪些工具?
答案 0 :(得分:23)
调试内核是 hard ,因为您可能无法依赖崩溃的机器来传达正在发生的事情。此外,错误的代码可能在中断处理程序等可怕的地方。
有四种调试操作系统的主要方法,我知道:
完整性检查以及输出到屏幕。
Linux上的内核恐慌(known as "Oops"es)就是一个很好的例子。 Linux人员编写了一个函数,可以打印出他们可以找到的内容(包括堆栈跟踪),然后停止所有内容。
即使警告也很有用。 Linux设置了防护装置,用于在中断处理程序中意外进入睡眠状态的情况。例如,mutex_lock函数将检查(在might_sleep中)您是否处于不安全的上下文中并打印堆栈跟踪。
调试
传统上,在调试过程中,计算机所做的一切都通过串行线输出到稳定的测试机器上。随着虚拟机的出现,您现在可以将一个VM的执行串行线路连接到同一物理机器上的另一个程序,这非常方便。但是,当然,这需要您的操作系统发布它正在执行的操作并等待调试器连接。 KGDB(Linux)和WinDBG(Windows)是一些这样的操作系统调试器。 VMWare supports this story explicitly。
最近,VM开发人员已经找到了如何在没有串行线或内核扩展的情况下调试内核。 VMWare has implemented this在他们最近的事情中。
在操作系统中调试的问题(在我看来)与Uncertainty principle有关。中断(大多数硬错误肯定是中断)是异步,频繁和不确定的。如果您的错误与特定方式的两个中断的重叠有关,您将不使用调试器公开它;这个bug甚至可能都不会发生。也就是说,它可能,然后调试器可能会有用。
确定性重播
当你遇到一个似乎只出现在制作中的错误时,你希望你能记录发生的事情并重放它,比如安全摄像头。感谢a professor I knew at Illinois,您现在可以在VMWare虚拟机中执行此操作。 VMWare和相关人员describe it all比我更好,他们提供了good documentation的内容。
确定性重播在现场是全新的,所以到目前为止我还没有意识到任何特别惯用的用法。他们说它对安全漏洞也应该特别有用。
将所有内容移至用户空间。
最后,内核中的内容仍然更加脆弱,因此遵循Nucleus(或Microkernel)设计有一个巨大的开发优势,在这种设计中,您可以将内核模式组件削减到最低限度。对于其他一切,你可以使用无数的用户空间开发工具,你会更开心。 FUSE是一个用户空间文件系统扩展,是 这个典型的例子。
我喜欢这个最后的想法,因为它就像你写的程序是可写的。循环,没有?
答案 1 :(得分:3)
您可以使用VM:例如。 debug ring0 code with bochs/gdb 或Debugging NetBSD kernel with qemu
或类似KDB的串行线。
答案 2 :(得分:3)
在引导程序场景(操作系统从头开始)中,您可能必须尽早在操作系统内核中引入远程调试功能(内存转储,日志记录等),并使用单独的计算机。或者您可以使用虚拟机/虚拟机管理程序。
Windows CE有一个名为KITL的组件 - 内核独立传输层。我想这个标题可以代替它。
答案 3 :(得分:1)
printf日志记录 附加到过程 严肃的单元测试 等。
答案 4 :(得分:0)
使用内核调试程序进行远程调试,也可以通过虚拟化完成。
答案 5 :(得分:0)
调试操作系统并不适合胆小的人。由于内核正在调试,因此您的选择将非常有限。大量的printf
语句是一个技巧,而且,它实际上取决于“操作系统”正在被调试,我们可以谈论
同样,它是一种广泛变化的练习,如上所述,它们都相互作用。更复杂的是,假设你要调试内核,如果没有正确设置运行时环境,你将如何做到(由此,我说的是内核负责加载二进制可执行文件)。
某些内核可能(并非所有人都拥有它们)都包含一个简单的调试监视器,事实上,如果我正确地回忆一下,在Sam出版的Richard A Burgess所着的“开发你自己的32位操作系统”一书中,他收录了一个调试监视器,显示CPU的各种状态,寄存器等。同样,考虑到二进制可执行文件需要某种加载机制的事实,例如gdb等价物,如果没有设置加载二进制文件的环境,那么你的选项非常有限。
通过使用大量的printf
语句来显示错误,日志等到单独的终端或文件是最好的调试线,它听起来确实是一场噩梦,但这样做是值得的。
希望这有帮助, 最好的祝福, 汤姆。