《Effective Debugging:软件和系统调试的66个有效方法》——第4条:从具体问题入手向上追查bug,或从高层程序入手向下追查bug...
发布日期:2021-09-03 11:45:58 浏览次数:1 分类:技术文章

本文共 2132 字,大约阅读时间需要 7 分钟。

本节书摘来自华章计算机《Effective Debugging:软件和系统调试的66个有效方法》一书中的第1章,第4节,作者[希]迪欧米迪斯·斯宾奈里斯(Diomidis Spinellis),爱飞翔 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

第4条:从具体问题入手向上追查bug,或从高层程序入手向下追查bug

要想确定问题的来源,通常有两种办法。一种是从问题的具体表现入手,向上追查其来源,还有一种是从应用程序或系统的顶层入手,逐步向下探查,直至找到其根源。对于某种类型的问题来说,其中一种方法的效果通常要比另一种更好,但是如果你在采用某个方法时遇到了困境,那么不妨试试另一个方法。

如果问题表现得很明确,那我们就应该从发生问题的地方入手,向上追查bug。这可以分成三种情况。

第一种情况是程序崩溃。在这种情况下,为了便于排查问题,我们通常可以考虑用调试器来运行程序,也可以在它崩溃的时候把调试器连接到程序上面,或取得内存转储信息(参见第35条)。我们要检查各变量在程序崩溃时的取值,看看有没有null值、损坏的值或未初始化的值,这些都有可能是引发崩溃的原因。对于某些系统来说,我们可以通过0xBAADF00D(代表bad food)这样的特殊字节值来找出尚未初始化的变量。维基百科的Magic Number词条列出了很多这样的特殊值。找到了取值不正确的变量之后,就应该设法查出导致此现象的原因,为此,我们可以试着在程序发生崩溃的这个例程之内探查,也可以沿着调用栈向上寻找不正确的参数或与崩溃有关的其他因素(参见第3条和第32条)。

如果这些办法找不到原因,那么可以用调试器来多次调试程序,每次都在有可能发生运算错误的地方附近设置断点。像这样反复地设置断点并沿着调用序列上移,或许可以帮助我们查出问题的原因。

第二种情况是程序冻结(freeze),这与程序崩溃有所区别,因此我们向上排查所用的办法也稍有不同。我们可以用调试器来运行程序,或将其连接到程序上面,然后用相应的调试器命令来中断其执行过程(参见第30条),或使程序生成内存转储信息(参见第35条)。有时你会发现,程序所执行的某些代码,并不是该程序自身的代码,而是某个程序库中的例程。无论中断发生在何处,我们都可以沿着调用栈向上排查,以便确定导致程序冻结的那个循环。检查该循环的终止条件,并试着找出它永远无法得到满足的原因。

第三种情况是程序在出现问题时发出了错误消息,此时我们首先应该在程序的源代码里找到消息文本的位置。这可以通过fgrep-r命令轻松地实现(参见第22条),该命令能够在任意深度和复杂度的目录结构中快速定位到待搜索的词句。对于当今很多本地化的软件来说,该命令所定位到的内容,通常并不是发出错误消息的那行代码,而是与错误消息相对应的那个字符串资源文件。例如,如果你住在讲西班牙语的地方,并且正在调试Inkscape绘图程序中与“Ha ocurrido un error al procesar el archivo XCF”错误消息有关的问题,那么用fgrep-r命令搜索Inkscape的源代码之后,它就可能会把你引向名为es.po的西班牙语字符串翻译文件:

image

从字符串翻译文件中,我们可以得知与错误消息相对应的源码位置(对于上例来说,就是share/extensions/gimp_xcf.py文件的第43行)。然后,我们可以在发出错误消息的源代码这里设置断点,或在它之前插入log语句,以检查程序运行到此处所发生的问题。在这种情况下,我们有可能也要后退几行或沿着调用栈向上回溯几层,才能够找到问题的根源。如果你要搜索的是非ASCII文本,那么请确保命令行的locale(区域)设置与源代码所用的文本编码(如UTF-8)相符。

如果无法确定与故障有关的代码到底在哪里,那我们就应该从顶层系统开始,逐步向下查找故障原因。从定义上来说,这种故障通常属于系统的涌现属性(emergent property),也就是无法与某个具体部分直接对应起来的属性,例如,性能问题(软件占用的内存过多或响应时间过长)、安全问题(Web应用程序的页面遭到破坏)以及可靠性问题(软件无法提供预期的Web服务)等。

要想由上而下地排查错误,我们需要把整个程序分成多个部分,然后分别判断每一部分在引发当前故障的各种因素中可能占多大的比例。对于性能问题来说,常见的办法是做profile(性能分析),也就是用一些工具和程序库来帮助我们寻找占用CPU资源及内存过多的例程。对于安全问题来说,我们要检查代码中有哪些地方可能出现常见的安全漏洞,如缓冲区溢出、代码注入以及跨站脚本攻击等。面对这类问题,我们也可以求助于一些代码分析工具(参见第51条)。最后,对于无法提供Web服务的问题来说,我们需要审视内部和外部的各种依赖关系,看看它们有没有在正常地运作。

要点

  • 如果能够明确指出故障的原因,那么应该从下往上查找错误,例如,在程序崩溃、程序冻结以及程序发出错误消息等情况下,就应该如此。
  • 如果故障的原因很难锁定,那么应该从上往下查找错误,例如,在遇到性能问题、安全问题以及可靠性问题的时候,就应该如此。

转载地址:https://blog.csdn.net/weixin_34186950/article/details/90504290 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:《数据科学:R语言实现》——3.11 检测缺失数据
下一篇:国家生态大数据研究院落户海南陵水

发表评论

最新留言

很好
[***.229.124.182]2024年03月02日 00时26分15秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

avs3 mkv格式封装_将你的视频无损封装成MP4,非转码哦! 2019-04-21
java http服务端_HTTP协议经典面试题整理及答案详解 2019-04-21
mysql 递归查找父节点_数据结构与算法—浅显易懂的二叉排序(查找)树 2019-04-21
body里写注释 postman_使用 Postman 做 API 自动化测试 2019-04-21
python3的配置文件类单例实现_Servlet是单例还多例 2019-04-21
写一个饿汉单例模式的例子_看完这篇单例模式,终于敢和面试官对线了 2019-04-21
华为手机的分类有何区别_动画有哪些分类?又有何区别? 2019-04-21
编程迷宫_跟我学编程第十期——迷宫游戏 2019-04-21
一键生成安卓证书_【带壳截图+电影台词 生成器】 2019-04-21
北斗轨迹记录_北斗定位+智慧4G视频校车行业解决方案 2019-04-21
存放哪些内容 项目中vuex_房屋安全鉴定中房屋抗震检测内容有哪些 2019-04-21
extjs的panel怎么自适应高度_Ext Js自适应高度 2019-04-21
ilm 和dlm差异_Oracle 的信息生命周期管理工具(ILM assistant) 2019-04-21
斥候密报_斥候密报《最强王者》三国幕后巾帼之黄月英_吉吉建站手游网 2019-04-21
python的循环控制结构是什么_7.Python控制和循环结构 2019-04-21
python 死循环插曲变量_FishC03 讲:python小插曲之变量和字符串 2019-04-21
车型代号对照表_车型代号对照表_相关文章专题_写写帮文库 2019-04-21
arcgis符号方向_ArcGIS制图表达-河流渐变与符号旋转 2019-04-21
springboot 实现机器学习_SpringBoot架构浅谈 2019-04-21
oss批量上传工具_OssExplorer一OSS的专用客户端工具【最新版】_Windows_Windows server 2008-云市场-阿里云... 2019-04-21