第1章 软件调试技术概述 1
1.1 软件系统的“双刃剑效应” 1
1.2 软件质量体系中的短板——调试技术 2
1.3 传统软件调试技术的局限性 4
1.4 软件调试技术的发展概况 8
1.5 本书的组织 11
第2章 型号软件中的bug分析 13
2.1 概述 13
2.2 国外型号软件中的bug 13
2.2.1 金星探测器水手1号 13
2.2.2 阿里安5 14
2.2.3 火星气候轨道器MCO 17
2.2.4 火星极地着陆器 19
2.2.5 Titan/Centaur/Milstar军事卫星 23
2.3 国内型号软件中的bug 26
2.3.1 优先级运算问题 26
2.3.2 程序结构不合理问题 27
2.3.3 初始化不完备问题 29
2.3.4 原子性破坏问题 31
第3章 软件bug分类及分布规律 34
3.1 软件bug概述 34
3.1.1 关于bug的起源 34
3.1.2 软件bug的定义 35
3.2 典型软件bug分类体系简介 36
3.2.1 Boris Beizer分类体系 36
3.2.2 IEEE 1044—1994分类体系 37
3.2.3 QJ 3026—1998分类体系 38
3.3 C语言软件bug分类体系 39
3.3.1 内存相关错误 42
3.3.2 初始化错误 46
3.3.3 计算错误 49
3.3.4 输入输出错误 54
3.3.5 控制流错误 55
3.3.6 数据处理解释错误 65
3.3.7 竞争类错误 67
3.3.8 平台相关错误 72
3.3.9 其他错误 76
3.4 当前软件bug分布规律分析 78
3.5 软件bug分布发展趋势 82
3.6 对软件调试技术的需求 83
第4章 内存类bug调试 84
4.1 内存类bug产生原因 84
4.1.1 内存类bug现状 84
4.1.2 动态内存管理 85
4.2 内存类错误调试支持工具 87
4.2.1 Insure++ 87
4.2.2 Purify 93
4.2.3 Valgrind 107
第5章 静态分析调试 113
5.1 静态分析概述 113
5.2 典型静态分析技术 113
5.2.1 基于规则的检查 113
5.2.2 符号执行 114
5.2.3 定理证明 115
5.2.4 类型推导 115
5.2.5 抽象解释 116
5.2.6 模型检测 116
5.3 静态分析工具 118
5.3.1 Testbed简介 118
5.3.2 其他静态分析工具简介 125
5.4 静态分析局限性 127
第6章 动态分片调试 135
6.1 什么是程序分片 135
6.1.1 程序分片的发展历史 137
6.1.2 程序分片的分类 138
6.1.3 程序分片的应用 138
6.2 静态分片 139
6.2.1 静态分片 139
6.2.2 Weiser的算法 140
6.2.3 Ottenstein的算法 141
6.2.4 基于系统依赖图的算法 143
6.2.5 静态分片和动态分片 144
6.3 动态分片 144
6.3.1 分片标准 145
6.3.2 def-use动态分片算法 146
6.3.3 Agrawal和Horgan的算法 148
6.4 分片调试实例 154
6.4.1 采用可信度剪枝的动态程序分片 155
6.4.2 Delta调试和动态分片相结合的软件调试方法 156
6.5 商品化的分片工具 163
第7章 Delta调试 168
7.1 Delta调试概述 168
7.2 Delta调试分类 169
7.2.1 简化 170
7.2.2 分离 171
7.3 Delta调试基本原理 172
7.3.1 简化算法 172
7.3.2 层次化Delta调试 175
7.3.3 分离故障起因 180
7.3.4 分离因果链 185
7.4 Delta调试工具举例 192
7.4.1 ASKIGOR 192
7.4.2 DDchange和DDstate 194
7.5 问题和局限性 196
第8章 统计调试 198
8.1 统计调试概述 198
8.1.1 统计调试的定义 198
8.1.2 统计调试的特点 199
8.1.3 统计调试的发展历史 200
8.2 统计原理 201
8.2.1 常用分布 201
8.2.2 常用定理及统计推断 202
8.3 统计调试分类 204
8.3.1 在线和离线统计调试 204
8.3.2 单一bug和多个bug定位 205
8.4 统计调试基本方法 206
8.4.1 矢量表示 206
8.4.2 特征选择 208
8.4.3 聚类 208
8.4.4 谓词排序 210
8.5 统计调试模型 210
8.5.1 T-Proximity模型 210
8.5.2 Liblit05模型 214
8.5.3 SOBER模型 217
8.5.4 R-Proximity模型 219
8.5.5 Vote模型 223
8.5.6 ARGUS模型 226
8.5.7 各模型比较 231
第9章 不变式调试 232
9.1 不变式相关概念 232
9.2 不变式的分类 234
9.2.1 循环不变式 234
9.2.2 函数的前置不变式和后置不变式 236
9.2.3 类不变式 237
9.3 不变式的应用 239
9.3.1 程序设计 239
9.3.2 辅助程序理解 240
9.3.3 程序版本验证 242
9.3.4 故障定位 243
9.3.5 软件重构 248
9.4 发现不变式的方法 250
9.4.1 不变式的静态发现技术 250
9.4.2 不变式的动态发现技术 251
9.4.3 静态和动态方法的对比 253
9.5 不变式发现工具 255
9.5.1 Daikon 255
9.5.2 DIDUCE 260
9.5.3 Agitator 261
第10章 难以重现类bug调试 262
10.1 重现bug的必要性 262
10.2 bug难以重现的原因 263
10.2.1 优先级逆转 264
10.2.2 中断导致bug难以重现 265
10.2.3 调试器对程序时序的影响 266
10.2.4 调试器对程序内容的影响 267
10.3 重放调试概述 268
10.3.1 重放调试的基本思想 268
10.3.2 重放调试的分类 269
10.4 基于虚拟机的全系统执行重放 271
10.4.1 bbreplayer系统框架 271
10.4.2 bbreplayer系统功能 272
10.4.3 bbreplayer实现 273
10.5 分布式系统的重放调试 279
10.5.1 Liblog的设计要求 279
10.5.2 Liblog的设计 280
10.5.3 挑战与解决方案 281
10.6 VMware新增功能介绍 283
10.6.1 简介 283
10.6.2 典型的应用场景 285
10.6.3 主要功能 286
10.6.4 主要应用 286
10.6.5 使用VAssert 286
第11章 体系结构扩展调试 288
11.1 通用调试技术的局限性 288
11.1.1 现有体系结构对软件调试的支持 290
11.1.2 系统结构扩展支持调试的趋势 297
11.2 体系结构扩展技术分类 297
11.2.1 冯·诺依曼体系结构 297
11.2.2 体系结构扩展对应方法 299
11.2.3 体系结构扩展方法分类 299
11.3 软件扩展调试系统 305
11.3.1 iWatcher 305
11.3.2 FullDebugger 311
第12章 基于数据挖掘的调试方法 320
12.1 数据挖掘支持调试 320
12.1.1 数据挖掘调试概述 320
12.1.2 基于数据挖掘的调试方法分类 324
12.1.3 相关数据挖掘技术 325
12.2 基于源代码的关联挖掘调试技术 337
12.3 基于程序行为分类的挖掘调试技术 346
12.3.1 基于程序计数器(PC)的不变式 347
12.3.2 AccMon 348
12.4 基于程序运行轨迹的挖掘调试技术 350
第13章 软件调试技术评价 354
13.1 软件调试技术评价体系概况 354
13.1.1 调试技术评价体系定义 354
13.1.2 调试技术评价体系的历史 354
13.1.3 调试技术评价体系的要求 355
13.2 调试技术评价基本方法 356
13.2.1 寻找能力 357
13.2.2 定位能力 357
13.2.3 性能 359
13.2.4 对潜在错误的影响 359
13.3 常见的调试技术评价基准程序 360
13.3.1 西门子套件 360
13.3.2 SPEC 2000性能套件 362
13.3.3 PEST套件 365
13.3.4 BugBench套件 365
13.3.5 IBM Haifa套件 367
13.3.6 Nofib-buggy套件 369
13.3.7 iBUGS工具及其数据集 371
参考文献 373