Why Programs Fail:系统化调试指南

Why Programs Fail:系统化调试指南
作 者: Andreas Zeller 王咏武;王咏刚
出版社: 电子工业出版社
丛编项:
版权说明: 本书为公共版权或经版权方授权,请支持正版图书
标 签: 软件测试及维护
ISBN 出版时间 包装 开本 页数 字数
未知 暂无 暂无 未知 0 暂无

作者简介

  本书提供作译者介绍Andreas Zeller是德国Saarland大学的计算机科学教授。他的研究方向集中在提高程序员的生产力方面:即哪些事情可以使程序员的生活和工作更轻松?在Linux和UNIX程序员中,Zeller因GNU DDD——一个拥有内嵌数据可视化机制的调试器前端——而享有盛名。在研究人员和高级程序员中,Zeller因为delta调试——一种可以自动分离计算机程序故障起因的技术——而声名显赫。.他的工作时间被平均地分给教学、阅读、写作、编程,以及在大西洋两岸飞来飞去。他与家人一起生活在德法边界德国一侧的...

内容简介

调试一直是软件开发过程中“最痛苦”的环节,本书有望改变这一现状,因为它将调试的科学原理与业界的实践经验有机地融合起来,阐释了有关发现和修正程序错误的最佳方法和实践过程。.本书一共分为15章,以系统化的方式向读者介绍了整个调试过程,从跟踪和重现故障开始,一直到自动化和简化测试用例,寻找故障最可能的来源,分离故障的起因和结果,并最终修正程序缺陷。本书不仅涵盖了delta调试、程序切片、观察、监视、断言、检测反常等多种基本的静态和动态程序分析技术,还用浅显的语言说明如何使用一些调试领域最前沿的高水平调试工具。..本书适于那些希望掌握如何以系统化和自动化的方式调试程序的计算机编程人员、及相关专业的研究生以及高年级本科生。...

图书目录

第1章 故障从哪里来 1

1.1 我的程序罢工了 1

1.2 从缺陷到故障 3

1.3 迷失在时空之中 5

1.4 从故障到修正 9

1.5 自动调试技术 14

1.6 BUG、失误、

1.6 还是缺陷? 18

1.7 概念 20

1.8 工具 21

1.9 进一步阅读指南 22

1.10 习题 23

第2章 跟踪问题 25

2.1 啊!这么多问题 25

2.2 报告问题 26

2.3 管理问题 29

2.4 问题分类 31

2.4.1 严重程度 31

2.4.2 优先级 32

2.4.3 标识 32

2.4.4 注释 32

2.4.5 通知 32

2.5 处理问题 32

2.6 管理问题跟踪过程 35

2.7 把需求看作问题 36

2.8 管理重复问题 37

2.9 关联问题和修正 39

2.10 关联问题和测试 41

2.11 概念 43

2.12 工具 44

2.13 进一步阅读指南 45

2.14 习题 46

第3章 让程序出错 48

3.1 调试测试 48

3.2 控制程序 50

3.3 在表现层测试 52

3.3.1 低级交互 52

3.3.2 系统级交互 54

3.3.3 高级交互 55

3.3.4 评估测试结果 56

3.4 在功能层测试 57

3.5 在单元层测试 59

3.6 分离单元 63

3.7 为调试而设计 66

3.8 预防未知问题 69

3.9 概念 70

3.10 工具 71

3.11 进一步阅读指南 72

3.12 习题 73

第4章 重现问题 75

4.1 调试过程的第一步 75

4.2 重现问题环境 76

4.3 重现程序运行过程 78

4.3.1 重现数据 80

4.3.2 重现用户交互 81

4.3.3 重现通信 83

4.3.4 重现时间 83

4.3.5 重现随机性 84

4.3.6 重现操作环境 85

4.3.7 重现调度 87

4.3.8 物理影响 89

4.3.9 调试工具的影响 90

4.4 重现系统交互 92

4.5 专注于单元 92

4.5.1 创建一个控制层 93

4.5.2 单元控制举例 94

4.5.3 伪对象 96

4.5.4 控制更多的交互 98

4.6 概念 99

4.7 工具 100

4.8 进一步阅读指南 100

4.9 习题 101

第5章 简化问题 103

5.1 简化问题 103

5.2 GECKO BUG马拉松 104

5.3 手工简化 107

5.4 自动简化 109

5.5 简化算法 111

5.6 简化用户交互 117

5.7 简化随机输入 118

5.8 快速简化 119

5.8.1 缓存 120

5.8.2 尽早结束 120

5.8.3 语法简化 121

5.8.4 分离差别,而不是

5.8.4 环境因素 122

5.9 概念 123

5.10 工具 124

5.11 进一步阅读指南 124

5.12 习题 125

第6章 科学调试 128

6.1 如何成为一个

6.1 调试专家 128

6.2 科学方法 129

6.3 应用科学方法 130

6.3.1 调试sample—准备 130

6.3.2 调试sample—假设1 132

6.3.3 调试sample—假设2 132

6.3.4 调试sample—假设3 132

6.3.5 调试sample—假设4 133

6.4 明确调试 134

6.5 记录日志 135

6.6 快速而杂乱的调试 136

6.7 算法调试 137

6.8 构造假设 140

6.9 程序推理技术 142

6.10 概念 144

6.11 进一步阅读指南 145

6.12 习题 146

第7章 推演错误 148

7.1 分离取值的来源 148

7.2 理解控制流 149

7.3 跟踪依赖关系 153

7.3.1 语句的效果 153

7.3.2 被影响语句 154

7.3.3 语句依赖关系 155

7.3.4 跟踪依赖关系 156

7.3.5 利用依赖关系 158

7.4 程序切片 159

7.4.1 前向片断 159

7.4.2 后向片断 159

7.4.3 片断运算 160

7.4.4 利用片断 162

7.4.5 可运行片断 162

7.5 推演代码的坏味道 163

7.6 静态分析的局限性 168

7.7 概念 172

7.8 工具 172

7.9 进一步阅读指南 173

7.10 习题 174

第8章 观察事实 177

8.1 观察状态 177

8.2 记录运行情况 178

8.2.1 日志记录函数 180

8.2.2 日志记录的框架 183

8.2.3 用方面记录日志 186

8.2.4 在二进制级别

8.2.4 记录日志 189

8.3 使用调试器 192

8.3.1 调试会话 193

8.3.2 控制运行过程 196

8.3.3 事后调试 197

8.3.4 记录数据日志 198

8.3.5 调用函数 198

8.3.6 修正与继续 199

8.3.7 嵌入式调试器 199

8.3.8 有关调试器的建议 200

8.4 查询事件 201

8.4.1 监视点 202

8.4.2 统一事件查询 203

8.5 可视化显示状态 205

8.6 概念 207

8.7 工具 208

8.8 进一步阅读指南 209

8.9 习题 210

第9章 跟踪错误来源 216

9.1 回溯推理 216

9.2 探查运行历史 217

9.3 动态切片 219

9.4 操作来源 222

9.5 捕获错误状态 225

9.6 概念 226

9.7 工具 227

9.8 进一步阅读指南 227

9.9 习题 227

第10章 断言预期结果 230

10.1 自动观察 230

10.2 基本断言 232

10.3 断言不变量 233

10.4 断言正确性 237

10.5 作为规格说明的断言 240

10.6 从断言到验证 241

10.7 参考运行过程 244

10.8 系统断言 246

10.8.1 用MALLOC_CHECK

10.8.1 检查堆 247

10.8.2 用ELECTRICFENCE

10.8.2 避免缓冲区溢出 248

10.8.3 用VALGRIND

10.8.3 检测内存错误 248

10.8.4 语言扩展 250

10.9 检查产品代码 252

10.10 概念 253

10.11 工具 254

10.12 进一步阅读指南 256

10.13 习题 258

第11章 检测反常 263

11.1 捕捉正常行为 263

11.2 比较覆盖情况 264

11.3 统计调试 269

11.4 从用户环境中

11.4 收集数据 270

11.5 动态不变量 272

11.6 运行时的不变量 276

11.7 从反常定位缺陷 278

11.8 概念 278

11.9 工具 279

11.10 进一步阅读指南 280

11.11 习题 281

第12章 起因与结果 283

12.1 起因和参照世界 283

12.2 验证起因 285

12.3 因果关系实践 285

12.4 寻找真实起因 288

12.5 缩小起因范围 289

12.6 缩小差别举例 289

12.7 公共环境 290

12.8 调试中的起因 291

12.9 概念 292

12.10 进一步阅读指南 292

12.11 习题 293

第13章 分离故障起因 296

13.1 自动分离起因 296

13.2 分离和简化 297

13.3 一种分离算法 299

13.4 实现分离 301

13.5 分离引发故障的输入 304

13.6 分离引发故障的

13.6 调度过程 305

13.7 分离引发故障的变化 307

13.8 问题和局限性 313

13.9 概念 315

13.10 工具 316

13.11 进一步阅读指南 316

13.12 习题 317

第14章 分离因果链 319

14.1 无用起因 319

14.2 捕捉程序状态 322

14.3 比较程序状态 325

14.4 分离相关程序状态 327

14.5 分离因果链 331

14.6 分离引发故障的代码 336

14.7 问题和风险 340

14.8 概念 342

14.9 工具 343

14.10 进一步阅读指南 343

14.11 习题 344

第15章 修正缺陷 346

15.1 定位缺陷 346

15.2 重点关注最可能的

15.2 错误 347

15.3 确认缺陷 350

15.3.1 是这个错误引发了

15.3.1 故障吗? 350

15.3.2 该起因真是

15.3.2 错误吗? 351

15.3.3 先思考,后修正 353

15.4 修正缺陷 353

15.4.1 故障不再出现

15.4.1 了吗? 353

15.4.2 修正会引入新

15.4.2 问题吗? 354

15.4.3 同样的差错会出现在

15.4.3 其他地方吗? 355

15.4.4 我完成所有

15.4.4 工作了吗? 355

15.5 变通方法 356

15.6 从差错中学习 357

15.7 概念 359

15.8 进一步阅读指南 360

15.9 习题 361

附录A 规范定义 363

A.1 Delta调试 363

A.1.1 配置 363

A.1.2 成功与故障

A.1.2 运行过程 363

A.1.3 测试 364

A.1.4 最小性 364

A.1.5 简化 364

A.1.6 差别 365

A.1.7 分离 366

A.2 内存状态图 366

A.2.1 规范结构 366

A.2.2 展开数据结构 368

A.2.3 匹配顶点与有

A.2.3 向边 369

A.2.4 计算公共子图 370

A.2.5 计算图的差别 370

A.2.6 应用部分状态

A.2.6 变化 373

A.2.7 捕获C状态 373

A.3 因果链 375

术语表 378

参考文献 382

索引 390

How To目录

如何调试程序 20

如何组织调试过程 43

如何跟踪需求 44

如何重新构建发布的版本 44

如何关联问题和修正 44

如何关联问题和测试 44

如何进行调试测试 71

如何自动运行程序 71

如何在表现层测试 71

如何在功能层测试 71

如何在单元层测试 71

如何分离单元 71

如何为调试而设计 71

如何预防未知问题 71

如何重现问题 99

如何重现问题环境 99

如何重现问题运行过程 99

如何重现单元的行为 99

如何简化测试用例 123

如何自动简化 123

如何加快自动简化的速度 124

如何分离故障起因 144

如何理解当前的问题 145

如何避免没完没了的调试过程 145

如何在某个函数或逻辑式程序中定位错误 145

如何快速而杂乱地调试程序 145

如何构造假设 145

如何基于程序进行推理 145

如何分离取值来源 172

如何进行程序切片 172

如何观察程序状态 207

如何封装和重用调试代码 207

如何观察崩溃程序的最后状态 207

如何探查程序运行历史 226

如何分离某一次特定运行过程中的取值来源 226

如何捕获错误状态 226

如何进行自动观察 253

如何使用断言 253

如何把程序与参考程序进行比较 254

如何确保内存的完整性 254

如何预防低级别语言的内存错误 254

如何确定反常行为 279

如何概括行为 279

如何检测反常 279

如何比较覆盖情况 279

如何对返回值进行采样 279

如何收集用户环境中的数据 279

如何确定不变量 279

如何证实因果关系 292

如何寻找起因 292

如何寻找真实起因 292

如何自动分离故障起因 315

如何分离输入中的故障起因 315

如何分离线程调度中的故障起因 315

如何分离引发故障的代码变化 315

如何理解故障在运行过程中的传播过程 342

如何捕捉程序状态 342

如何比较程序状态 342

如何分离引发故障的程序状态 342

如何寻找引发故障的代码 343

如何沿着因果链缩小缺陷的范围 343

如何分离感染链 359

如何寻找最可能的来源 359

如何修正缺陷 360

如何确保修正是正确的 360

如何避免引入新问题 360

如何从错误中学习 360