以下《软件调试》的读者可能会问到的一些问题。简要罗列和回答如下。如果您有其它问题或者觉得回答不够全面,那么可以通过意见反馈栏目列出的方式进一步与作者和其他读者进行讨论。
为什么要重视软件调试?
在作者看来,当一个软件工程师掌握了基本的软件知识和概念后,那么接下来要学习的最重要技能便是软件调试。根本原因有两个:
- 使用调试技术可以更好的控制软件。相对于硬件,软件更加复杂、多变,有时甚至狡黠、事故和邪恶。大的方面讲,计算机历史上的重大灾难大多是软件导致的。从小的方面讲,用户遇到的崩溃、病毒入侵、没有响应等,也大多是由软件导致的。人类在控制和驾驭软件方面的能力还在发展的过程中。目前阶段,以调试器为核心的调试技术是征服软件的最强大武器。举例来说,目前有太多的糟糕软件完全不把自己当作“仆人”,它们自作主张,借助强大的计算机硬件恣意妄为,这时最有效的方法就是使用调试器将其擒获。当我们使用调试器来自由操纵桀骜的软件和被调试的计算机系统时,我们才真正找回了主人的尊严。如果我们不得不重新安装整个系统,那么就好像是为了赶走一个糟糕的仆人而重建“家园”。
- 使用调试技术可以更精确、更直接认识的软件。当我们一步步的跟踪一个软件时,我们对它的认识精确到了指令的级别。指令是软件的本质,是承载思维的载体,软件的好坏和善恶忠奸都在它的指令中,所以在指令一级的认识软件方式对于软件工程师来说是非常重要的。因为时间关系,我们可能无法跟踪软件的每一条语句或者指令,但是我们有必要仔细跟踪关键的操作和可能存在问题的代码片段。
终上,软件调试技术对于认识和控制软件都有着重要作用。一旦掌握了这门技术,便可以在很多方面获益:
- 侦错,即定位和修正瑕疵。
- 学习新的软硬件技术。
- 安全。以研究Rootkit著称的Joanna Rutkowska在接受采访时曾经说她的计算机系统不安装任何“安全软件”,但是她安装了调试器,并且说“MS Kernel Debugger can be very useful tool for system compromise detection”
很多资深的计算机专家都非常重视软件调试,比如以开创MSDN杂志的Under The Hood专栏著称的Matt Pietriek在给本书的短评中就说,调试器是所有系统程序员必须掌握的工具。尽管他没有说所有程序员,但这并不意味着,其他程序员学习调试器没有价值。而只是说,系统程序的复杂度和重要性,要求我们必须用调试器这样的强大工具。编写应用软件时,徒手或者土办法还能应付。对于其他程序员来说,既然有更好和更高效的工具,那我们为什么不用呢?
《Linux内核源代码情景分析》的两位作者在他们的《嵌入式系统》一书中谈到调试曾经说,在软件开发的“生命周期”中,程序调试(debug)以及调试手段的重要性是“怎么强调也不为过”的。
这本书为什么这么厚?
简单来说,因为太多的内容需要写。
软件调试如此重要,但是太多人对它还知之甚少,而且很难找到好的资料来学习。在写这本书之前,我仔细搜索了的关于调试的中外图书。但是没能找到一本我理想中的关于软件调试的书。
- 我希望这本书具有一般性,探讨调试的一般原理和思想,但是又不空泛,对于关键的技术应该讲透、讲彻底。
- 我希望这本书有理论价值,但又不脱离实践,讲的应该是当代主流的软硬件环境和工具,而不是多年前的,也不是实验性的,讨论的应该是“真家伙”,面对的应该“真难题”。因为调试软件是打仗,纸上谈兵似的东西没有用。
- 我希望这本书介绍必要的软硬件基础。打仗要熟悉地形,调试软件要熟悉软件所运行的基础环境,最起码的就是CPU、操作系统和编译器。如果对这三样东西模棱两可,那么打仗时难免晕头转向。
发现还没有这样一本书之后,与其等待,不如自己来,于是我决定写这样一本书。按照上面的“希望”有了构思和框架后,漫长的写作开始了。大约每完成一篇,我会统计一下已经达到的厚度和可能的厚度。在完成第3篇后,我开始有意识的控制篇幅。在重构第3篇时,删除了长达60页的整整一章,那一章花了不只一个月时间,这次心痛的体验让我更重视后面的写作计划。
在开始编辑这本书时,我们也考虑这本书的厚度,排版尽可能紧凑,在不影响阅读的情况下,有效利用空间。比如略微缩小行距,增大字体。在编辑的后期,所有页数统计出来后,我和编辑还是做了一个痛苦的决定,再删!于是又删减了大约70页正文和一个20多页的附录,成为目前的1006页。
这本书为什么没有详细讲Linux有关的内容?
正如前面谈到的,写作这本书的一个基本原则是,有一般性而且有不流于空泛。因此我们选择例子时尽可能使其具有更广泛的代表性。考虑到Windows操作系统的流行性,我们选择了以Windows系统作为本书的操作系统实例。
这本书是否适合初学者阅读?
初学者是个很模糊的概念,因此这个问题很难直接回答。我建议有这个问题的朋友先在网络上免费阅读本书的前言和样章。然后自己判断是否适合阅读这本书。
在做2.7.5节的实验时,遇到的情况为什么和书中讲的不一样?
您使用的系统可能启用了CPU的物理地址扩展(即PAE)功能,如果是这样,那么请您参阅《使用WinDBG观察启用PAE后的分页机制》一文来做这个实验。如果是仍然遇到困难,那么请发电子邮件和我联系或者把问题发到高端调试网站中《软件调试》答疑论坛中。
在VS2002/2003/2005/2008下重新编译第3章的Fault程序后,程序为什么不断的循环?
这是因为编译器在编译除法语句nResult=nDividend/nDivisor时,将除数先放到了寄存器中,这样在异常处理中虽然将除数改为非零,但是寄存器中的除数还是零。请参考下面的讨论做修改:
关于第三章Fault演示程序的疑问。
|