展开全部

主编推荐语

堪称是软件调试的“百科全书”,软件工程师的贴身宝典。

内容简介

本书堪称是软件调试的“百科全书”。作者围绕软件调试的“生态”系统(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 本章小结
  • 参考资料
展开全部

评分及书评

评分不足
2个评分
  • 用户头像
    给这本书评了
    4.0
    调试

    这本书粗略阅读,可以看到作者大大对调试支持和理解比较深入。分享下我的 debug 的经验 1. 优先解决那些可重现的,可重现的 bug 特别好找,反复调试测试就好了,先把好解决的干掉,这样最节约时间。2. 对于某些 bug 没有头绪或者现象古怪不知道从哪里下手,找有经验的同事问一下思路,因为在那种开发多年的大型系统里,经常会反复出现同样原因的 bug,原因都类似,改了一处,过一阵子另外一处又冒出来,而且无法根治。比如:我那个系统里有个特别危险的 API,接口参数比较难用,一旦有人用错了某些情况下就会出诡异的现象,解决很简单,找到调用这个 API 的地方把调用方式写对就好了。为什么不根治呢?因为要保持兼容性不能改接口了。Windows 系统里就好多这种烂 API。问下老员工吧,说不定他们都遇到过好多次了。3. 放大现象,有些 bug 现象不太明显,那么就想办法增大它的破坏性,把现象放大。这只是个思路,具体怎么放大只能根据具体的代码来定。比如:美剧《豪斯医生》里有一集,怀疑病人心肺有问题,就让病人去跑步机上跑步,加重心肺负担,从而放大症状。4. 二分法定位,把程序逻辑一点点注释掉,看看还会不会出问题,类似二分查找的方法,逐步缩小问题范围。5. 模拟现场,有时候我会问自己,如果我要实现 bug 描述的现象我要怎么写代码才行?比如:我遇到一个死锁问题,但是检查代码发现所有的锁都是配对的,没有忘记解锁的地方,而且锁很简单就是一个普通的临界段,保护几行赋值语句而已。这样的代码怎么写才能让他死锁呢?我想如果让我故意制造这样一个现象,只有在上锁的时候强制杀掉线程了。既然这样就可以去看看有谁强杀线程了没有。6. 制作工具,针对某些 bug 编写一些调试辅助工具。

      转发
      评论

    出版方

    人民邮电出版社

    人民邮电出版社是工业和信息化部主管的大型专业出版社,成立于1953年10月1日。人民邮电出版社坚持“立足信息产业、面向现代社会、传播科学知识、服务科教兴国”,致力于通信、计算机、电子技术、教材、少儿、经管、摄影、集邮、旅游、心理学等领域的专业图书出版。