1 引 言

软件规模 日趋庞大 , 软件调试 中 , 发现 、 定位、分析错误的工作量也相应增长 。 因此 , 人们 开发 了 C o d e iV e w 等调试工具以 深 入错 误发 生时的程序执行环 境 , 使效率大增 。 不过对于 下 面的循环结构 ( 以 C 语言为例 )仍有为难之处 :

 

 

假定该循环共执行 1 0 0 0 0 遍 , 第 3 0 0 0 次执行死 机了 , 那么用调试工具判定死机发生在该循环 中很 容易 , 但再进一步分析则不可能 。 因为 , 若 设 断点 于 循 环 内 , 则 每 次循 环 皆被 中断 , 至 3 0 0 0 次运行才能发现错误所在 , 以 后欲 分析错 误也是每 3 0 0 0 次运行方可进入 出错环境一次 , 这绝对无法 容忍。

2 调试方法

在这里笔者介绍一种在调试软件过程中改 进了的方法 , 可解决这个问题 。 对于上面的实例 只需增加几条语句即可 , 如下所示 。 其 中 fp 为 文件 指针 , n u m b e r 是 初 值 为零 的整 型 变 量 ,
d o o n h t in g 为一空 函数 , 它 们都为调试而 设立 。 具体的调试方法是将不设断点的程序先执行一 次 , 然后 阅读 r e c o r d . da t 找 出错 误发 生 时的n u m be r 值 , 再设 br e a k p o in t 为该 n u m be r 值 , 置断点于 d o n o t h i n g o 这 一行上 , 即可使 程序 非常方便地运行到 出错处停住 。

 

这里文件先 用 “ w ” 方 式打开 , 就 自然清 除 了上次执行形成的 r e c o r d . da t 。 在循环中用“ a " 方式将每次循 环 中的 n u m h a r 值等关键参数逐 次记入文件尾 部 。 切记一定要在循环内打开文 件 , 写 入信息 , 再关 闭文件 , 这可保证切实形 成 文件 ; 否则 (在进入循环 前打开 , 结束循环后关 闭) , 一旦循环 内出现死机等严重间题 , 文件就 不能形成 。 对于复杂的循环 , 记录于文件 中的信 息应包含一些除 n u m b e r 外 的其 他重 要参 数 , 既 利于发现错误 ( 参数异常就是出错 , 不必非死 机等重大问题才知出错了 ) , 又有利于了解循环 执行过程 而分析错误 , 因此 , 这些参数选择的好 坏 直接 影响调试效率。 在这个例子 中设 do_mai n _ w o r k 为循环 中的实质所在 , 又 很复 杂 , 其余仅是简 . 单工作 , 则应记录它的参数 ( 假设参 数 1 为整型 , 参数 2 为双精度型 ) 。

n u m b e r 系一附加 变量 , 如循环 中有一 不 断 增大或不断减小的变量可用 , 则也可用该变 量代替 n u m b e r 的作用 。 不过本例适用于 任何 循环 , 则是标准的方法 。 另外 i f 语句中的相等 关系也可用适当的不等关 系取代 , 如本例中用 不小于关 系 , 则 n u m b e r 不小于 b r e a k p o i n t 后 的每一 次循环 中断点有效 。 b r e a k p i o n t 最好不 要用一常量 ( 以免常常修改 ) , 而采用一变量 , 它 可在进入循环 前读入或 由命令行参数传入 , 如 此则程序无须改 动而 可停在循环的任意次数 上 。 b r e a kp o in t 类型 自然与 n u m b e r 或其他替 代者相同 。

3 结 语

这种方法有利于 发现错误 , 以 后 利用调试 工具又极易进入 出错时的环境 , 而且为调试而增加的程 序是固定不 变的 , 故大大提高了效率 。 不过除了死机 、 除零等中断程序运行的错 误一 定发生在 r e c o r d . d a t 的最后 一行记录写入 后外 , 其余错误往往 比较含蓄而要查找一番 , 如 关 键参 数出错 , 则可能需要认真 阅读 r e c o r .d
da t , 对于一些不影响关键参数的小错则可能需 要另 想办法 。 另外发现的可能是表面错误 , 如果 死机 由前面 某次循 环中的错误 埋下祸 根 , 则需 先 由 死 机 处 仔 细 分 析 , 发 现 疑 点 , 再 重 设
b r e a k p o f n t 去分析疑点 , 深挖根源 . 所 以使用该 法虽减小了工作量 , 但软件调试仍是一项艰 巨 的任务 .

标签: none

添加新评论