1. 高级调试概念

1.1 调试模式深入

用户模式调试进阶

进程附加策略

# 非侵入式附加
windbg -pv -p <PID>      # 附加但不中断进程
windbg -pvr -p <PID>     # 附加并允许进程继续运行

# 子进程调试
windbg -o notepad.exe    # 调试notepad及其子进程

调试会话管理

# 分离调试器
.detach                  # 分离调试器但保持进程运行
.kill                    # 终止被调试进程
.abandon                 # 放弃调试会话

# 会话信息
.ttime                   # 显示目标执行时间
.effmach                 # 显示有效机器类型

内核模式调试进阶

内核调试连接类型

# 串口调试
windbg -k com:port=COM1,baud=115200

# 网络调试
windbg -k net:port=50000,key=1.2.3.4

# USB调试
windbg -k usb:targetname=MyTarget

# 1394调试
windbg -k 1394:channel=1

内核调试控制

# 中断目标系统
Ctrl+Break               # 强制中断
.crash                   # 触发系统崩溃
.reboot                  # 重启目标系统

# 内核状态查看
!process 0 0             # 显示所有进程
!thread                  # 显示当前线程信息
!irql                    # 显示当前IRQL级别

1.2 调试目标类型

转储文件分析

转储文件类型

# 小型转储(Mini Dump)
.dump /m c:\mini.dmp     # 创建小型转储

# 完整转储(Full Dump)
.dump /ma c:\full.dmp    # 创建完整转储

# 内核转储
.dump /k c:\kernel.dmp   # 创建内核转储

# 活动转储
.dump /mA c:\active.dmp  # 创建活动内存转储

转储文件信息

!analyze -v              # 自动分析转储
.dumpdebug               # 显示转储创建信息
.time                    # 显示转储时间
!vm                      # 显示虚拟内存状态

远程调试

调试服务器设置

# 启动调试服务器
windbg -server tcp:port=5005 -p <PID>

# 连接到调试服务器
windbg -remote tcp:server=192.168.1.100,port=5005

# 进程服务器
dbgsrv -t tcp:port=5006
windbg -premote tcp:server=192.168.1.100,port=5006 -p <PID>

远程调试管理

.clients                 # 显示连接的客户端
.endpsrv                 # 结束进程服务器
.endsrv                  # 结束调试服务器

2. 内存分析技术

2.1 堆分析

堆基础信息

!heap                    # 显示所有堆
!heap -s                 # 堆统计信息
!heap -a                 # 显示所有堆的详细信息
!heap -h <堆地址>        # 显示特定堆信息

堆损坏检测

!heap -p                 # 启用页堆
!heap -p -h <堆地址>     # 检查特定堆的页堆状态
!heap -x <地址>          # 查找地址所属的堆块
!heap -flt s <大小>      # 查找指定大小的堆块

堆泄漏分析

# 启用堆跟踪
gflags -i myapp.exe +hpa +hpc

# 分析堆泄漏
!heap -stat -h 0        # 详细堆统计
!heap -flt s 100        # 查找100字节的分配
!heap -p -a <地址>       # 显示分配调用堆栈

2.2 虚拟内存分析

虚拟内存布局

!address                 # 显示虚拟内存布局
!address -summary        # 虚拟内存摘要
!address <地址>          # 显示特定地址的内存信息
!vadump                  # 转储VAD树

内存保护和属性

!vprot <地址>            # 显示内存保护属性
!vm                      # 虚拟内存统计
!poolused                # 内核池使用情况
!memusage                # 内存使用分析

内存泄漏检测

# 用户模式内存泄漏
!heap -stat -h 0
!heap -flt s 0x1000     # 查找4KB分配

# 内核模式内存泄漏
!poolused 2             # 显示非分页池使用
!poolfind <标签>         # 查找特定标签的池分配

2.3 句柄分析

句柄信息

!handle                  # 显示所有句柄
!handle 0 f              # 显示所有句柄的详细信息
!handle <句柄值>         # 显示特定句柄信息
!handle 0 f File         # 显示所有文件句柄

句柄泄漏检测

# 句柄计数
!process <进程地址> 1    # 显示进程句柄信息

# 句柄跟踪
gflags -i myapp.exe +htc # 启用句柄跟踪
!htrace                  # 显示句柄跟踪信息

3. 线程和同步分析

3.1 线程状态分析

线程信息

~                        # 显示所有线程
~*k                      # 显示所有线程堆栈
~<线程号>s               # 切换到指定线程
!thread                  # 显示当前线程详细信息
!thread <线程地址>       # 显示特定线程信息

线程状态

!runaway                 # 显示线程CPU使用时间
!runaway 7               # 详细的线程时间信息
!ready                   # 显示就绪线程
!running                 # 显示正在运行的线程

线程上下文

.thread <线程地址>       # 设置线程上下文
.cxr <上下文地址>        # 设置上下文记录
.trap <陷阱帧地址>       # 设置陷阱帧

3.2 同步对象分析

临界区分析

!cs                      # 显示所有临界区
!cs -l                   # 显示锁定的临界区
!cs <地址>               # 显示特定临界区信息
!cs -o                   # 显示临界区所有者

互斥体和事件

!handle 0 f Mutant       # 显示所有互斥体
!handle 0 f Event        # 显示所有事件
!object <对象地址>       # 显示对象信息

死锁检测

!deadlock                # 检测死锁
!locks                   # 显示内核锁信息
!irql                    # 显示IRQL级别
!spinlock <地址>         # 显示自旋锁信息

3.3 等待链分析

等待链显示

!wdfkd.wdfwaitlock       # WDF等待锁分析
!analyze -hang           # 分析挂起问题
!analyze -hang -v        # 详细挂起分析

阻塞分析

# 查找阻塞线程
~*k                      # 所有线程堆栈
!uniqstack               # 唯一堆栈
!findstack <符号>        # 查找包含特定符号的堆栈

4. 异常和错误分析

4.1 异常处理机制

异常记录分析

.exr -1                  # 显示最后异常记录
.exr <异常记录地址>      # 显示特定异常记录
.cxr <上下文地址>        # 显示异常上下文

异常类型分析

# 访问违例分析
!analyze -v              # 自动分析访问违例
ln <故障地址>            # 查找故障地址符号
!address <故障地址>      # 分析故障地址内存属性

# 堆栈溢出分析
!analyze -v
k 100                    # 显示深层堆栈
!address @esp            # 检查堆栈内存

SEH链分析

!exchain                 # 显示SEH链
!exchain /f              # 显示完整SEH链
!cppexr                  # 分析C++异常

4.2 崩溃分析技术

自动崩溃分析

!analyze -v              # 详细自动分析
!analyze -hang           # 挂起分析
!analyze -f              # 函数分析
!analyze -D              # 默认分析

手动崩溃分析

# 分析步骤
1. 检查异常信息: .exr -1
2. 设置异常上下文: .cxr <地址>
3. 查看调用堆栈: k
4. 分析故障指令: u @eip
5. 检查内存状态: !address <故障地址>
6. 查看模块信息: lm

蓝屏分析

# 内核崩溃分析
!analyze -v              # 自动分析蓝屏
!bugcheck                # 显示蓝屏代码
!error <错误代码>        # 解释错误代码
!vm                      # 虚拟内存状态
!process 0 0             # 进程列表

4.3 错误代码分析

Windows错误代码

!error <错误代码>        # 解释Windows错误代码
!gle                     # 显示最后错误
!teb                     # 显示TEB信息

NTSTATUS代码

!error <NTSTATUS>        # 解释NTSTATUS代码
.formats <数值>          # 显示数值的各种格式

5. 性能分析技术

5.1 CPU性能分析

CPU使用率分析

!runaway                 # 线程CPU时间
!runaway 7               # 详细CPU时间信息
.time                    # 显示时间信息
!perfctr                 # 性能计数器

热点函数分析

# 采样分析
bp kernel32!* "g"        # 在所有kernel32函数设置断点
!uniqstack               # 分析唯一堆栈

指令级性能分析

# 单步性能测试
.time; t; .time          # 测量单条指令时间

# 函数性能测试
.time; gu; .time         # 测量函数执行时间

5.2 内存性能分析

内存分配性能

!heap -stat -h 0        # 堆分配统计
!heap -flt s 0x1000     # 查找大块分配
!poolused                # 内核池使用

缓存性能分析

!vm                      # 虚拟内存统计
!pfn <页帧号>            # 页帧信息
!memusage                # 内存使用分析

5.3 I/O性能分析

文件I/O分析

!handle 0 f File         # 显示文件句柄
!irp                     # 显示I/O请求包
!devobj <设备对象>       # 设备对象信息

网络I/O分析

!handle 0 f Socket       # 显示套接字句柄
!netstat                 # 网络连接状态

6. 驱动程序调试

6.1 驱动程序基础调试

驱动程序信息

!drvobj <驱动对象>       # 显示驱动对象信息
!devobj <设备对象>       # 显示设备对象信息
!devnode 0 1             # 显示设备节点树
lm t n                   # 按类型列出模块

驱动程序加载

.load <驱动路径>         # 加载驱动符号
.unload <模块名>         # 卸载模块
!reload <模块名>         # 重新加载模块符号

6.2 I/O请求分析

IRP分析

!irp <IRP地址>           # 显示IRP信息
!irpfind <设备对象>      # 查找设备的IRP
!irpzone                 # 显示IRP区域

I/O堆栈分析

!irp <IRP地址> 1         # 显示IRP和I/O堆栈
!iospace                 # 显示I/O空间

6.3 即插即用调试

PnP设备树

!devnode 0 1             # 显示设备树
!devnode <设备节点> 1    # 显示特定设备节点
!arbiter 4               # 显示仲裁器信息

电源管理

!poaction                # 显示电源操作
!popolicy                # 显示电源策略
!potrigger               # 显示电源触发器

7. .NET和托管代码调试

7.1 .NET调试扩展

SOS扩展加载

.loadby sos clr          # 加载SOS扩展(.NET Framework)
.loadby sos coreclr      # 加载SOS扩展(.NET Core)

基本.NET信息

!version                 # 显示CLR版本
!eeversion               # 显示执行引擎版本
!threads                 # 显示托管线程
!clrstack                # 显示托管调用堆栈

7.2 托管堆分析

堆信息

!eeheap                  # 显示托管堆信息
!eeheap -gc              # 显示GC堆信息
!heapstat                # 堆统计信息
!dumpheap                # 转储堆对象

对象分析

!do <对象地址>           # 显示对象信息
!dumpobj <对象地址>      # 转储对象
!objsize <对象地址>      # 显示对象大小
!gcroot <对象地址>       # 查找GC根

7.3 垃圾回收分析

GC信息

!gcinfo                  # 显示GC信息
!gchandles               # 显示GC句柄
!finalizequeue           # 显示终结队列
!syncblk                 # 显示同步块

内存泄漏分析

!dumpheap -stat          # 按类型统计堆对象
!dumpheap -mt <方法表>   # 转储特定类型的对象
!gcroot <对象地址>       # 查找对象引用链

8. 脚本和自动化

8.1 WinDbg脚本

脚本文件

# 创建脚本文件 debug.wds
.echo "Starting automated analysis"
!analyze -v
k
lm
.echo "Analysis complete"

# 执行脚本
$$>< c:\debug.wds

条件脚本

# 条件执行脚本
.if (@eax == 0) {
    .echo "EAX is zero"
    k
} .else {
    .echo "EAX is not zero"
    r eax
}

8.2 JavaScript脚本

JavaScript扩展

// 示例JavaScript脚本
function analyzeThreads() {
    var control = host.namespace.Debugger.Utility.Control;
    var output = control.ExecuteCommand("~*k");
    
    host.diagnostics.debugLog("Thread analysis:\n");
    for (var line of output) {
        host.diagnostics.debugLog(line + "\n");
    }
}

// 执行脚本
.scriptload c:\analyze_threads.js
dx @$scriptContents.analyzeThreads()

数据模型扩展

// 扩展数据模型
class ProcessAnalyzer {
    get Threads() {
        return host.currentProcess.Threads;
    }
    
    get HeapInfo() {
        var control = host.namespace.Debugger.Utility.Control;
        return control.ExecuteCommand("!heap -s");
    }
}

// 注册扩展
host.namedModelParents.ProcessAnalyzer = ProcessAnalyzer;

8.3 自动化调试流程

批量分析脚本

@echo off
echo Batch dump analysis starting...

for %%f in (*.dmp) do (
    echo Analyzing %%f
    windbg -z "%%f" -c "!analyze -v; .logopen %%f.log; k; lm; .logclose; q"
)

echo Batch analysis complete

持续监控脚本

# 监控脚本 monitor.wds
.while (1) {
    .echo "=== Monitoring at:" 
    .time
    !runaway
    !heap -s
    .sleep 5000
}

9. 高级分析案例

9.1 内存损坏分析

堆损坏检测

# 启用页堆
gflags -i myapp.exe +hpa

# 分析堆损坏
!heap -p -h 0            # 检查页堆状态
!heap -p -a <地址>       # 显示分配信息
!heap -p -l              # 显示泄漏信息

缓冲区溢出分析

# 分析访问违例
!analyze -v
.exr -1                  # 异常记录
.cxr <上下文地址>        # 设置上下文
k                        # 调用堆栈
u @eip                   # 反汇编故障指令
!address <故障地址>      # 内存属性

9.2 性能问题分析

CPU占用过高

# 分析CPU使用
!runaway 7               # 详细线程时间
~*k                      # 所有线程堆栈
!uniqstack               # 唯一堆栈分析

# 热点函数分析
bp kernel32!* "g"        # 函数调用统计

内存泄漏分析

# 用户模式内存泄漏
!heap -stat -h 0        # 堆统计
!heap -flt s 0x1000     # 大块分配

# 托管内存泄漏
!dumpheap -stat          # 托管堆统计
!gcroot <对象地址>       # 引用链分析

9.3 死锁分析

用户模式死锁

!cs -l                   # 锁定的临界区
!cs -o                   # 临界区所有者
~*k                      # 所有线程堆栈
!analyze -hang           # 挂起分析

内核模式死锁

!deadlock                # 死锁检测
!locks                   # 内核锁信息
!thread                  # 线程信息
!irql                    # IRQL级别

小结

本章深入介绍了WinDbg的高级调试和分析技术:

  1. 高级调试概念:掌握了用户模式和内核模式的高级调试技巧
  2. 内存分析技术:学习了堆分析、虚拟内存分析和句柄分析
  3. 线程和同步分析:了解了线程状态分析和同步对象分析
  4. 异常和错误分析:掌握了异常处理机制和崩溃分析技术
  5. 性能分析技术:学习了CPU、内存和I/O性能分析方法
  6. 驱动程序调试:了解了驱动程序和I/O请求的调试技巧
  7. .NET调试:掌握了托管代码的调试和分析方法
  8. 脚本和自动化:学习了脚本编写和自动化调试流程
  9. 高级分析案例:通过实际案例学习了复杂问题的分析方法

下一章将学习WinDbg在实际项目中的应用和最佳实践。