第1篇 绪论 1
第1章 软件调试基础 3
第2篇 CPU的调试支持 27
第2章 CPU基础 29
第3章 中断和异常 65
第4章 断点和单步执行 75
第5章 分支记录和性能监视 107
第6章 机器检查架构(MCA) 133
第7章 JTAG调试 147
第3篇 操作系统的调试支持 163
第8章 Windows概要 165
第9章 用户态调试模型 193
第10章 用户态调试过程 227
第11章 中断和异常管理 273
第12章 未处理异常和JIT调试 309
第13章 硬错误和蓝屏 359
第14章 错误报告 391
第15章 日志 405
第16章 事件追踪 421
第17章 WHEA 445
第18章 内核调试引擎 461
第19章 Windows的验证机制 513
第4篇 编译器的调试支持 539
第20章 编译和编译期检查 541
第21章 运行库和运行期检查 559
第22章 栈和函数调用 581
第23章 堆和堆检查 643
第24章 异常处理代码的编译 711
第25章 调试符号 739
第5篇 可调试性 781
第26章 可调试性概览 783
第27章 可调试性的实现 801
第6篇 调度器 833
第28章 调试器概览 835
第29章WinDBG及其实现 867
第30章winDBG用法详解 905
附录A 示例程序列表 999
附录B WinDBG标准命令列表 1001
索引 1003
第1篇 绪论 1
第1章 软件调试基础 3
1.1简介 3
1.2基本特征 6
1.3简要历史 8
1.4分类 12
1.5调试技术概览 15
1.6错误与缺欠 20
1.7与软件工程的关系 24
1.8本章总结 26
第2篇 CPU的调试支持 27
第2章 CPU基础 29
2.1指令和指令集 29
2.2 IA-32处理器 32
2.3 CPU的操作模式 38
2.4寄存器 40
2.5理解保护模式 46
2.6段机制 50
2.7分页机制(Paging) 55
2.8系统概貌 62
2.9本章总结 64
第3章 中断和异常 65
3.1概念和差异 65
3.2异常的分类 67
3.3异常例析 69
3.4中断/异常优先级 72
3.5中断/异常处理 73
3.6本章总结 74
第4章 断点和单步执行 75
4.1软件断点 75
4.2硬件断点 83
4.3陷阱标志 95
4.4实模式调试器例析 100
4.5本章总结 105
第5章 分支记录和性能监视 107
5.1分支监视概览 107
5.2使用寄存器的分支记录 108
5.3使用内存的分支记录 113
5.4 DS示例:CpuWhere 117
5.5性能监视 123
5.6本章总结 132
第6章 机器检查架构(MCA) 133
6.1奔腾处理器的机器检查机制 134
6.2 MCA 135
6.3编写MCA软件 141
6.4本章总结 145
第7章 JTAG调试 147
7.1简介 147
7.2 JTAG原理 149
7.3 JTAG应用 154
7.4 IA-32处理器的JTAG支持 156
7.5本章总结 161
第3篇 操作系统的调试支持 163
第8章 Windows概要 165
8.1简介 165
8.2进程和进程空间 167
8.3内核模式和用户模式 176
8.4架构和系统部件 184
8.5本章总结 192
第9章 用户态调试模型 193
9.1概览 193
9.2采集调试消息 196
9.3发送调试消息 200
9.4调试子系统服务器(XP之后) 203
9.5调试子系统服务器(XP之前) 210
9.6比较两种模型 219
9.7 NTDLL中的调试支持例程 221
9.8调试API 224
9.9本章总结 226
第10章 用户态调试过程 227
10.1调试器进程 227
10.2被调试进程 231
10.3从调试器中启动被调试程序 234
10.4附加到已经启动的进程 240
10.5处理调试事件 243
10.6中断到调试器 251
10.7输出调试字符串 259
10.8终止调试会话 266
10.9本章总结 271
第11章 中断和异常管理 273
11.1中断描述符表 273
11.2异常的描述和登记 280
11.3异常分发过程 284
11.4结构化异常处理(SEH) 290
11.5向量化异常处理(VEH) 302
11.6本章总结 308
第12章 未处理异常和JIT调试 309
12.1简介 309
12.2默认的异常处理器 311
12.3未处理异常过滤函数 318
12.4应用程序错误对话框 328
12.5 JIT调试和Dr.Watson 334
12.6顶层异常过滤函数 340
12.7 Dr.Watson 343
12.8 DRWTSN32的日志文件 347
12.9用户态转储文件 351
12.10本章总结 357
第13章 硬错误和蓝屏 359
13.1硬错误提示 359
13.2蓝屏终止(BSOD) 366
13.3系统转储文件 371
13.4分析系统转储文件 374
13.5辅助的错误提示方法 380
13.6配置错误提示机制 384
13.7防止滥用错误提示机制 389
13.8本章总结 390
第14章 错误报告 391
14.1 WER 1.0 392
14.2系统错误报告 395
14.3 WER服务器端 397
14.4 WER 2.0 399
14.5 CER 403
14.6本章总结 404
第15章 日志 405
15.1日志简介 405
15.2 ELF的架构 406
15.3 ELF的数据组织 409
15.4察看和使用ELF日志 413
15.5 CLFS的组成和原理 414
15.6 CLFS的使用方法 416
15.7本章总结 420
第16章 事件追踪 421
16.1简介 421
16.2 ETW的架构 422
16.3提供ETW消息 424
16.4控制ETW会话 425
16.5 消耗ETW消息 427
16.6格式描述 428
16.7 NT Kernel Logger 432
16.8 Global Logger Session 436
16.9 Crimson API 440
16.10本章总结 443
第17章 WHEA 445
17.1目标和架构 445
17.2错误源 450
17.3错误处理过程 452
17.4错误持久化 457
17.5注入错误 459
17.6本章总结 459
第18章 内核调试引擎 461
18.1概览 462
18.2连接 465
18.3启用 475
18.4初始化 478
18.5内核调试协议 483
18.6与内核交互 492
18.7建立和维持连接 502
18.8 本地内核调试 509
18.9本章总结 511
第19章 Windows的验证机制 513
19.1简介 514
19.2驱动验证器的工作原理 515
19.3使用驱动验证器 521
19.4应用程序验证器的工作原理 526
19.5使用应用程序验证器 533
19.6本章总结 537
第4篇 编译器的调试支持 539
第20章 编译和编译期检查 541
20.1程序的构建过程 541
20.2编译 543
20.3 Visual C++编译器 544
20.4编译错误和警告 549
20.5编译期检查 551
20.6标准标注语言 555
20.7本章总结 558
第21章 运行库和运行期检查 559
21.1 C/C++运行库 559
21.2链接运行库 562
21.3运行库的初始化和清理 565
21.4运行期检查 569
21.5报告运行期检查错误 574
21.6本章总结 580
第22章 栈和函数调用 581
22.1简介 581
22.2栈的创建过程 585
22.3 CALL和RET指令 590
22.4局部变量和栈帧 595
22.5帧指针省略(FPO) 604
22.6栈指针检查 606
22.7调用协定 609
22.8栈空间的增长和溢出 616
22.9栈下溢 623
22.10缓冲区溢出 624
22.11变量检查 628
22.12基于Cookie的安全检查 636
22.13本章总结 642
第23章 堆和堆检查 643
23.1理解堆 644
23.2堆的创建和销毁 646
23.3分配和释放堆块 649
23.4堆的内部结构 654
23.5低碎片堆(LFH) 661
23.6堆的调试支持 662
23.7栈回溯数据库 666
23.8堆溢出和检测 670
23.9页堆 677
23.10准页堆 683
23.11 CRT堆 688
23.12 CRT堆的调试堆块 692
23.13 CRT堆的调试功能 698
23.14堆块转储 700
23.15泄漏转储 704
23.16本章总结 709
第24章 异常处理代码的编译 711
24.1概览 711
24.2 FS:[0]链条 713
24.3遍历FS:[0]链条 716
24.4执行异常处理函数 721
24.5_try{}—except()结构 724
24.6安全问题 732
24.7本章总结 737
第25章 调试符号 739
25.1名称修饰 739
25.2调试信息的存储格式 742
25.3目标文件中的调试信息 745
25.4PE文件中的调试信息 753
25.5DBG文件 762
25.6PDB文件 764
25.7有关的编译和链接选项 771
25.8PDB文件中的数据表 775
25.9本章总结 780
第5篇 可调试性 781
第26章 可调试性概览 783
26.1简介 783
26.2 Showstopper和未雨绸缪 784
26.3基本原则 787
26.4不可调试代码 792
26.5可调试性例析 794
26.6与安全、性能和商业秘密的关系 798
26.7本章总结 799
第27章 可调试性的实现 801
27.1角色和职责 801
27.2可调试架构 804
27.3通过栈回溯实现可追溯性 808
27.4数据的可追溯性 815
27.5可观察性的实现 821
27.6自检和自动报告 830
27.7本章总结 832
第6篇 调试器 833
第28章 调试器概览 835
28.1TX-0计算机和FLIT调试器 835
28.2小型机和DDT调试器 837
28.3个人计算机和它的调试器 841
28.4调试器的功能 845
28.5分类标准 852
28.6实现模型 853
28.7经典架构 859
28.8HPD标准 862
28.9本章总结 866
第29章 WinDBG及其实现 867
29.1WinDBG溯源 867
29.2C阶段的架构 872
29.3重构 875
29.4调试器引擎的架构 881
29.5调试目标 887
29.6调试会话 892
29.7接收和处理命令 899
29.8本章总结 904
第30章 WinDBG用法详解 905
30.1工作空间 905
30.2命令概览 908
30.3用户界面 911
30.4输入和执行命令 916
30.5建立调试会话 923
30.6终止调试会话 927
30.7理解上下文 930
30.8调试符号 933
30.9事件处理 944
30.10控制调试目标 951
30.11单步执行 955
30.12使用断点 962
30.13控制进程和线程 969
30.14观察栈 973
30.15分析内存 978
30.16遍历链表 987
30.17调用目标程序的函数 992
30.18命令程序 994
30.19本章总结 997
附录A 示例程序列表 999
附录B WinDBG标准命令列表 1001
索引 1003