主编推荐语
堪称是软件调试的“百科全书”,软件工程师的贴身宝典。
内容简介
本书堪称是软件调试的“百科全书”。作者围绕软件调试的“生态”系统(ecosystem)、异常(exception)和调试器3条主线,介绍软件调试的相关原理和机制,探讨可调试性(debuggability)的内涵、意义以及实现软件可调试性的原则和方法,总结软件调试的方法和技巧。 第1卷主要围绕硬件技术展开介绍。全书分为4篇,共16章。第一篇“绪论”(第1章),介绍了软件调试的概念、基本过程、分类和简要历史,并综述了本书后面将详细介绍的主要调试技术。第二篇“CPU及其调试设施”(第2~7章),以英特尔和ARM架构的CPU为例系统描述了CPU的调试支持。第三篇“GPU及其调试设施”(第8~14章),深入探讨了Nvidia、AMD、英特尔、ARM和Imagination 这五大厂商的GPU。第四篇“可调试性”(第15~16章),介绍了提高软件可调试性的意义、基本原则、实例和需要注意的问题,并讨论了如何在软件开发实践中实现可调试性。 本书理论与实践紧密结合,既涵盖了相关的技术背景知识,又针对大量具有代表性和普遍意义的技术细节进行了讨论,是学习软件调试技术的宝贵资料。
本书适合所有从事软件开发工作的读者阅读,特别适合从事软件开发、测试、支持的技术人员,从事反病毒、网络安全、版权保护等工作的技术人员,以及高等院校相关专业的教师和学生学习参考。
目录
- 版权信息
- 内容提要
- 历史回眸
- 第2版前言
- 第1版前言
- 资源与支持
- 第一篇 绪论
- 第1章 软件调试基础
- 1.1 简介
- 1.1.1 定义
- 1.1.2 基本过程
- 1.2 基本特征
- 1.2.1 难度大
- 1.2.2 难以估计完成时间
- 1.2.3 广泛的关联性
- 1.3 简要历史
- 1.3.1 单步执行
- 1.3.2 断点指令
- 1.3.3 分支监视
- 1.4 分类
- 1.4.1 按调试目标的系统环境分类
- 1.4.2 按目标代码的执行方式分类
- 1.4.3 按目标代码的执行模式分类
- 1.4.4 按软件所处的阶段分类
- 1.4.5 按调试器与调试目标的相对位置分类
- 1.4.6 按调试目标的活动性分类
- 1.4.7 按调试工具分类
- 1.5 调试技术概览
- 1.5.1 断点
- 1.5.2 单步执行
- 1.5.3 输出调试信息
- 1.5.4 日志
- 1.5.5 事件追踪
- 1.5.6 转储文件
- 1.5.7 栈回溯
- 1.5.8 反汇编
- 1.5.9 观察和修改内存数据
- 1.5.10 控制被调试进程和线程
- 1.6 错误与缺欠
- 1.6.1 内因与表象
- 1.6.2 谁的bug
- 1.6.3 bug的生命周期
- 1.6.4 软件错误的开支曲线
- 1.7 重要性
- 1.7.1 调试与编码的关系
- 1.7.2 调试与测试的关系
- 1.7.3 调试与逆向工程的关系
- 1.7.4 学习调试技术的意义
- 1.7.5 调试技术尚未得到应有的重视
- 1.8 本章小结
- 参考资料
- 第二篇 CPU及其调试设施
- 第2章 CPU基础
- 2.1 指令和指令集
- 2.1.1 基本特征
- 2.1.2 寻址方式
- 2.1.3 指令的执行过程
- 2.2 英特尔架构处理器
- 2.2.1 80386处理器
- 2.2.2 80486处理器
- 2.2.3 奔腾处理器
- 2.2.4 P6系列处理器
- 2.2.5 奔腾4处理器
- 2.2.6 Core 2系列处理器
- 2.2.7 Nehalem微架构
- 2.2.8 Sandy Bridge微架构
- 2.2.9 Ivy Bridge微架构
- 2.2.10 Haswell微架构
- 2.2.11 Broadwell微架构
- 2.2.12 Skylake微架构
- 2.2.13 Kaby Lake微架构
- 2.3 CPU的操作模式
- 2.4 寄存器
- 2.4.1 通用数据寄存器
- 2.4.2 标志寄存器
- 2.4.3 MSR寄存器
- 2.4.4 控制寄存器
- 2.4.5 其他寄存器
- 2.4.6 64位模式时的寄存器
- 2.5 理解保护模式
- 2.5.1 任务间的保护机制
- 2.5.2 任务内的保护
- 2.5.3 特权级
- 2.5.4 特权指令
- 2.6 段机制
- 2.6.1 段描述符
- 2.6.2 描述符表
- 2.6.3 段选择子
- 2.6.4 观察段寄存器
- 2.7 分页机制
- 2.7.1 32位经典分页
- 2.7.2 PAE分页
- 2.7.3 IA-32e分页
- 2.7.4 大内存页
- 2.7.5 WinDBG的有关命令
- 2.8 PC系统概貌
- 2.9 ARM架构基础
- 2.9.1 ARM的多重含义
- 2.9.2 主要版本
- 2.9.3 操作模式和状态
- 2.9.4 32位架构核心寄存器
- 2.9.5 协处理器
- 2.9.6 虚拟内存管理
- 2.9.7 伪段支持
- 2.9.8 64位ARM架构
- 2.10 本章小结
- 参考资料
- 第3章 中断和异常
- 3.1 概念和差异
- 3.1.1 中断
- 3.1.2 异常
- 3.1.3 比较
- 3.2 异常的分类
- 3.2.1 错误类异常
- 3.2.2 陷阱类异常
- 3.2.3 中止类异常
- 3.3 异常例析
- 3.3.1 列表
- 3.3.2 错误代码
- 3.3.3 示例
- 3.4 中断/异常的优先级
- 3.5 中断/异常处理
- 3.5.1 实模式
- 3.5.2 保护模式
- 3.5.3 IA-32e模式
- 3.6 ARM架构中的异常机制
- 3.7 本章小结
- 参考资料
- 第4章 断点和单步执行
- 4.1 软件断点
- 4.1.1 INT 3
- 4.1.2 在调试器中设置断点
- 4.1.3 断点命中
- 4.1.4 恢复执行
- 4.1.5 特殊用途
- 4.1.6 断点API
- 4.1.7 系统对INT 3的优待
- 4.1.8 观察调试器写入的INT 3指令
- 4.1.9 归纳和提示
- 4.2 硬件断点
- 4.2.1 调试寄存器概览
- 4.2.2 调试地址寄存器
- 4.2.3 调试控制寄存器
- 4.2.4 指令断点
- 4.2.5 调试异常
- 4.2.6 调试状态寄存器
- 4.2.7 示例
- 4.2.8 硬件断点的设置方法
- 4.2.9 归纳
- 4.3 陷阱标志
- 4.3.1 单步执行标志
- 4.3.2 高级语言的单步执行
- 4.3.3 任务状态段陷阱标志
- 4.3.4 按分支单步执行标志
- 4.4 实模式调试器例析
- 4.4.1 Debug.exe
- 4.4.2 8086 Monitor
- 4.4.3 关键实现
- 4.5 反调试示例
- 4.6 ARM架构的断点支持
- 4.6.1 断点指令
- 4.6.2 断点寄存器
- 4.6.3 监视点寄存器
- 4.6.4 单步跟踪
- 4.7 本章小结
- 参考资料
- 第5章 分支记录和性能监视
- 5.1 分支监视概览
- 5.2 使用寄存器的分支记录
- 5.2.1 LBR
- 5.2.2 LBR栈
- 5.2.3 示例
- 5.2.4 在Windows操作系统中的应用
- 5.3 使用内存的分支记录
- 5.3.1 DS区
- 5.3.2 启用DS机制
- 5.3.3 调试控制寄存器
- 5.4 DS示例:CpuWhere
- 5.4.1 驱动程序
- 5.4.2 应用界面
- 5.4.3 2.0版本
- 5.4.4 局限性和扩展建议
- 5.4.5 Linux内核中的BTS驱动
- 5.5 性能监视
- 5.5.1 奔腾处理器的性能监视机制
- 5.5.2 P6处理器的性能监视机制
- 5.5.3 P4处理器的性能监视
- 5.5.4 架构性的性能监视机制
- 5.5.5 酷睿微架构处理器的性能监视机制
- 5.5.6 资源
- 5.6 实时指令追踪
- 5.6.1 工作原理
- 5.6.2 RTIT数据包
- 5.6.3 Linux支持
- 5.7 ARM架构的性能监视设施
- 5.7.1 PMUv1和PMUv2
- 5.7.2 PMUv3
- 5.7.3 示例
- 5.7.4 CoreSight
- 5.8 本章小结
- 参考资料
- 第6章 机器检查架构
- 6.1 奔腾处理器的机器检查机制
- 6.2 MCA
- 6.2.1 概览
- 6.2.2 MCA的全局寄存器
- 6.2.3 MCA的错误报告寄存器
- 6.2.4 扩展的机器检查状态寄存器
- 6.2.5 MCA错误编码
- 6.3 编写MCA软件
- 6.3.1 基本算法
- 6.3.2 示例
- 6.3.3 在Windows系统中的应用
- 6.3.4 在Linux系统中的应用
- 6.4 本章小结
- 参考资料
- 第7章 JTAG调试
- 7.1 简介
- 7.1.1 ICE
- 7.1.2 JTAG
- 7.2 JTAG原理
- 7.2.1 边界扫描链路
- 7.2.2 TAP信号
- 7.2.3 TAP寄存器
- 7.2.4 TAP控制器
- 7.2.5 TAP指令
- 7.3 JTAG应用
- 7.3.1 JTAG调试
- 7.3.2 调试端口
- 7.4 IA处理器的JTAG支持
- 7.4.1 P6处理器的JTAG实现
- 7.4.2 探测模式
- 7.4.3 ITP接口
- 7.4.4 XDP端口
- 7.4.5 ITP-XDP调试仪
- 7.4.6 直接连接接口
- 7.4.7 典型应用
- 7.5 ARM处理器的JTAG支持
- 7.5.1 ARM调试接口
- 7.5.2 调试端口
- 7.5.3 访问端口
- 7.5.4 被调试器件
- 7.5.5 调试接插口
- 7.5.6 硬件调试器
- 7.5.7 DS-5
- 7.6 本章小结
- 参考资料
- 第三篇 GPU及其调试设施
- 第8章 GPU基础
- 8.1 GPU简史
- 8.1.1 从显卡说起
- 8.1.2 硬件加速
- 8.1.3 可编程和通用化
- 8.1.4 三轮演进
- 8.2 设备身份
- 8.2.1 “喂模式”
- 8.2.2 内存复制
- 8.2.3 超时检测和复位
- 8.2.4 与CPU之并立
- 8.3 软件接口
- 8.3.1 设备寄存器
- 8.3.2 批命令缓冲区
- 8.3.3 状态模型
- 8.4 GPU驱动模型
- 8.4.1 WDDM
- 8.4.2 DRI和DRM
- 8.5 编程技术
- 8.5.1 着色器
- 8.5.2 Brook和CUDA
- 8.5.3 OpenCL
- 8.6 调试设施
- 8.6.1 输出调试信息
- 8.6.2 发布断点
- 8.6.3 其他断点
- 8.6.4 单步执行
- 8.6.5 观察程序状态
- 8.7 本章小结
- 参考资料
- 第9章 Nvidia GPU及其调试设施
- 9.1 概要
- 9.1.1 一套微架构
- 9.1.2 三条产品线
- 9.1.3 封闭
- 9.2 微架构
- 9.2.1 G80(特斯拉1.0微架构)
- 9.2.2 GT200(特斯拉2.0微架构)
- 9.2.3 GF100(费米微架构)
- 9.2.4 GK110(开普勒微架构)
- 9.2.5 GM107(麦斯威尔微架构)
- 9.2.6 GP104(帕斯卡微架构)
- 9.2.7 GV100(伏特微架构)
- 9.2.8 持续改进
- 9.3 硬件指令集
- 9.3.1 SASS
- 9.3.2 指令格式
- 9.3.3 谓词执行
- 9.3.4 计算能力
- 9.3.5 GT200的指令集
- 9.3.6 GV100的指令集
- 9.4 PTX指令集
- 9.4.1 汇编和反汇编
- 9.4.2 状态空间
- 9.4.3 虚拟寄存器
- 9.4.4 数据类型
- 9.4.5 指令格式
- 9.4.6 内嵌汇编
- 9.5 CUDA
- 9.5.1 源于Brook
- 9.5.2 算核
- 9.5.3 执行配置
- 9.5.4 内置变量
- 9.5.5 Warp
- 9.5.6 显式并行
- 9.6 异常和陷阱
- 9.6.1 陷阱指令
- 9.6.2 陷阱后缀
- 9.6.3 陷阱处理
- 9.7 系统调用
- 9.7.1 vprintf
- 9.7.2 malloc和free
- 9.7.3 __assertfail
- 9.8 断点指令
- 9.8.1 PTX的断点指令
- 9.8.2 硬件的断点指令
- 9.9 Nsight的断点功能
- 9.9.1 源代码断点
- 9.9.2 函数断点
- 9.9.3 根据线程组和线程编号设置条件断点
- 9.10 数据断点
- 9.10.1 设置方法
- 9.10.2 命中
- 9.10.3 数量限制
- 9.10.4 设置时机
- 9.11 调试符号
- 9.11.1 编译选项
- 9.11.2 ELF载体
- 9.11.3 DWARF
- 9.12 CUDA GDB
- 9.12.1 通用命令
- 9.12.2 扩展
- 9.12.3 局限
- 9.13 CUDA调试器API
- 9.13.1 头文件
- 9.13.2 调试事件
- 9.13.3 工作原理
- 9.14 本章小结
- 参考资料
- 第10章 AMD GPU及其调试设施
- 10.1 演进简史
- 10.1.1 三个发展阶段
- 10.1.2 两种产品形态
- 10.2 Terascale微架构
- 10.2.1 总体结构
- 10.2.2 SIMD核心
- 10.2.3 VLIW
- 10.2.4 四类指令
- 10.3 GCN微架构
- 10.3.1 逻辑结构
- 10.3.2 CU和波阵
- 10.3.3 内存层次结构
- 10.3.4 工作组
- 10.3.5 多执行引擎
- 10.4 GCN指令集
- 10.4.1 7种指令类型
- 10.4.2 指令格式
- 10.4.3 不再是VLIW指令
- 10.4.4 指令手册
- 10.5 编程模型
- 10.5.1 地幔
- 10.5.2 HSA
- 10.5.3 ROCm
- 10.5.4 Stream SDK和APP SDK
- 10.5.5 Linux系统的驱动
- 10.6 异常和陷阱
- 10.6.1 9种异常
- 10.6.2 启用
- 10.6.3 陷阱状态寄存器
- 10.6.4 陷阱处理器基地址
- 10.6.5 陷阱处理过程
- 10.7 控制波阵的调试接口
- 10.7.1 5种操作
- 10.7.2 指定目标
- 10.7.3 发送接口
- 10.7.4 限制
- 10.8 地址监视
- 10.8.1 4种监视模式
- 10.8.2 数量限制
- 10.8.3 报告命中
- 10.8.4 寄存器接口
- 10.8.5 用户空间接口
- 10.9 单步调试支持
- 10.9.1 单步调试模式
- 10.9.2 控制方法
- 10.10 根据调试条件实现分支跳转的指令
- 10.10.1 两个条件标志
- 10.10.2 4条指令
- 10.11 代码断点
- 10.11.1 陷阱指令
- 10.11.2 在GPU调试SDK中的使用
- 10.12 GPU调试模型和开发套件
- 10.12.1 组成
- 10.12.2 进程内调试模型
- 10.12.3 面向事件的调试接口
- 10.13 ROCm-GDB
- 10.13.1 源代码
- 10.13.2 安装和编译
- 10.13.3 常用命令
- 10.14 本章小结
- 参考资料
- 第11章 英特尔GPU及其调试设施
- 11.1 演进简史
- 11.1.1 i740
- 11.1.2 集成显卡
- 11.1.3 G965
- 11.1.4 Larabee
- 11.1.5 GPU
- 11.1.6 第三轮努力
- 11.1.7 公开文档
- 11.2 GEN微架构
- 11.2.1 总体架构
- 11.2.2 片区布局
- 11.2.3 子片布局
- 11.2.4 EU
- 11.2.5 经典架构图
- 11.3 寄存器接口
- 11.3.1 两大类寄存器
- 11.3.2 显示功能的寄存器
- 11.4 命令流和环形缓冲区
- 11.4.1 命令
- 11.4.2 环形缓冲区
- 11.4.3 环形缓冲区寄存器
- 11.5 逻辑环上下文和执行列表
- 11.5.1 LRC
- 11.5.2 执行链表提交端口
- 11.5.3 理解LRC的提交和执行过程
- 11.6 GuC和通过GuC提交任务
- 11.6.1 加载固件和启动GuC
- 11.6.2 以MMIO方式通信
- 11.6.3 基于共享内存的命令传递机制
- 11.6.4 提交工作任务
- 11.7 媒体流水线
- 11.7.1 G965的媒体流水线
- 11.7.2 MFX引擎
- 11.7.3 状态模型
- 11.7.4 多种计算方式
- 11.8 EU指令集
- 11.8.1 寄存器
- 11.8.2 寄存器区块
- 11.8.3 指令语法
- 11.8.4 VLIW和指令级别并行
- 11.9 内存管理
- 11.9.1 GGTT
- 11.9.2 PPGTT
- 11.9.3 I915和GMMLIB
- 11.10 异常
- 11.10.1 异常类型
- 11.10.2 系统过程
- 11.11 断点支持
- 11.11.1 调试控制位
- 11.11.2 操作码匹配断点
- 11.11.3 IP匹配断点
- 11.11.4 初始断点
- 11.12 单步执行
- 11.13 GT调试器
- 11.13.1 架构
- 11.13.2 调试事件
- 11.13.3 符号管理
- 11.13.4 主要功能
- 11.13.5 不足
- 11.14 本章小结
- 参考资料
- 第12章 Mali GPU及其调试设施
- 12.1 概况
- 12.1.1 源于挪威
- 12.1.2 纳入ARM
- 12.1.3 三代微架构
- 12.1.4 发货最多的图形处理器
- 12.1.5 精悍的团队
- 12.1.6 封闭的技术文档
- 12.1.7 单元化设计
- 12.2 Midgard微架构
- 12.2.1 逻辑结构
- 12.2.2 三流水线着色器核心
- 12.2.3 VLIW指令集
- 12.3 Bifrost微架构
- 12.3.1 逻辑结构
- 12.3.2 执行核心
- 12.3.3 标量指令集和Warp
- 12.4 Mali图形调试器
- 12.4.1 双机模式
- 12.4.2 面向帧调试
- 12.5 Gator
- 12.5.1 Gator内核模块(gator.ko)
- 12.5.2 Gator文件系统(gatorfs)
- 12.5.3 Gator后台服务(gatord)
- 12.5.4 Kbase驱动中的gator支持
- 12.5.5 含义
- 12.6 Kbase驱动的调试设施
- 12.6.1 GPU版本报告
- 12.6.2 编译选项
- 12.6.3 DebugFS下的虚拟文件
- 12.6.4 SysFS下的虚拟文件
- 12.6.5 基于ftrace的追踪设施
- 12.6.6 Kbase的追踪设施
- 12.7 其他调试设施
- 12.7.1 Caiman
- 12.7.2 devlib
- 12.7.3 Mali离线编译器
- 12.8 缺少的调试设施
- 12.8.1 GPGPU调试器
- 12.8.2 GPU调试SDK
- 12.8.3 反汇编器
- 12.8.4 ISA文档
- 12.9 本章小结
- 参考资料
- 第13章 PowerVR GPU及其调试设施
- 13.1 概要
- 13.1.1 发展简史
- 13.1.2 两条产品线
- 13.1.3 基于图块延迟渲染
- 13.1.4 Intel GMA
- 13.1.5 开放性
- 13.2 Rogue微架构
- 13.2.1 总体结构
- 13.2.2 USC
- 13.2.3 ALU流水线
- 13.3 参考指令集
- 13.3.1 寄存器
- 13.3.2 指令组
- 13.3.3 指令修饰符
- 13.3.4 指令类型
- 13.3.5 标量指令
- 13.3.6 并行模式
- 13.4 软件模型和微内核
- 13.4.1 软件模型
- 13.4.2 微内核的主要功能
- 13.4.3 优点
- 13.4.4 存在的问题
- 13.5 断点支持
- 13.5.1 bpret指令
- 13.5.2 数据断点
- 13.5.3 ISP断点
- 13.6 离线编译和反汇编
- 13.6.1 离线编译
- 13.6.2 反汇编
- 13.7 PVR-GDB
- 13.7.1 跟踪调试
- 13.7.2 寄存器访问
- 13.7.3 其他功能
- 13.7.4 全局断点和局限性
- 13.8 本章小结
- 参考资料
- 第14章 GPU综述
- 14.1 比较
- 14.1.1 开放性
- 14.1.2 工具链
- 14.1.3 开发者文档
- 14.2 主要矛盾
- 14.2.1 专用性和通用性
- 14.2.2 强硬件和弱软件
- 14.3 发展趋势
- 14.3.1 从固定功能单元到通用执行引擎
- 14.3.2 从向量指令到标量指令
- 14.3.3 从指令并行到线程并行
- 14.4 其他GPU
- 14.4.1 Adreno
- 14.4.2 VideoCore
- 14.4.3 图芯GPU
- 14.4.4 TI TMS34010
- 14.5 学习资料和工具
- 14.5.1 文档
- 14.5.2 源代码
- 14.5.3 工具
- 14.6 本章小结
- 参考资料
- 第四篇 可调试性
- 第15章 可调试性概览
- 15.1 简介
- 15.2 观止和未雨绸缪
- 15.2.1 NT 3.1的故事
- 15.2.2 未雨绸缪
- 15.3 基本原则
- 15.3.1 最短距离原则
- 15.3.2 最小范围原则
- 15.3.3 立刻终止原则
- 15.3.4 可追溯原则
- 15.3.5 可控制原则
- 15.3.6 可重复原则
- 15.3.7 可观察原则
- 15.3.8 易辨识原则
- 15.3.9 低海森伯效应原则
- 15.4 不可调试代码
- 15.4.1 系统的异常分发函数
- 15.4.2 提供调试功能的系统函数
- 15.4.3 对调试器敏感的函数
- 15.4.4 反跟踪和调试的程序
- 15.4.5 时间敏感的代码
- 15.4.6 应对措施
- 15.5 可调试性例析
- 15.5.1 健康性检查和BSOD
- 15.5.2 可控制性
- 15.5.3 公开的符号文件
- 15.5.4 WER
- 15.5.5 ETW和日志
- 15.5.6 性能计数器
- 15.5.7 内置的内核调试引擎
- 15.5.8 手动触发崩溃
- 15.6 与安全、商业秘密和性能的关系
- 15.6.1 可调试性与安全性
- 15.6.2 可调试性与商业秘密
- 15.6.3 可调试性与性能
- 15.7 本章小结
- 参考资料
- 第16章 可调试性的实现
- 16.1 角色和职责
- 16.1.1 架构师
- 16.1.2 程序员
- 16.1.3 测试人员
- 16.1.4 产品维护和技术支持工程师
- 16.1.5 管理者
- 16.2 可调试架构
- 16.2.1 日志
- 16.2.2 输出调试信息
- 16.2.3 转储
- 16.2.4 基类
- 16.2.5 调试模型
- 16.3 通过栈回溯实现可追溯性
- 16.3.1 栈回溯的基本原理
- 16.3.2 利用DbgHelp函数库回溯栈
- 16.3.3 利用RTL函数回溯栈
- 16.4 数据的可追溯性
- 16.4.1 基于数据断点的方法
- 16.4.2 使用对象封装技术来追踪数据变化
- 16.5 可观察性的实现
- 16.5.1 状态查询
- 16.5.2 WMI
- 16.5.3 性能计数器
- 16.5.4 转储
- 16.5.5 打印或者输出调试信息
- 16.5.6 日志
- 16.6 自检和自动报告
- 16.6.1 BIST
- 16.6.2 软件自检
- 16.6.3 自动报告
- 16.7 本章小结
- 参考资料
出版方
人民邮电出版社
人民邮电出版社是工业和信息化部主管的大型专业出版社,成立于1953年10月1日。人民邮电出版社坚持“立足信息产业、面向现代社会、传播科学知识、服务科教兴国”,致力于通信、计算机、电子技术、教材、少儿、经管、摄影、集邮、旅游、心理学等领域的专业图书出版。