Windbg常用命令总结查看线程中的堆栈信息
a. ~打印出所有的线程信息
b. !teb命令查看线程控制块中的信息，如StatckBase: 01820000
c. dps 01820000则可以看到线程运行的StackTrace
或者使用如下命令：
dds 0096a000 00970000 ; stackbase:0096a000 stacklimit:00970000
同样可以查看线程当前的执行堆栈
d. 在其中出现符号调用的地址，如0184eef0。在该位置展开堆栈可采用如下命令：k =0184eef0。就能够还原该部分堆栈，查看其对应的栈针信息。
注：查看指定内存位置的堆栈信息可以通过“=[address]”来指定。
查看module的描述信息
a. lmv m driver可以查看module加载后的开始和结束位置，若开始位置为：f5022000。Windbg还提供了其他查看模块加载状态的命令，如lmD vm Watchdog；lmv a [address]只显示包含指定地址的模块。
b. !dh f5022000 -f可查看该module的头信息，其中会记录module各字段的起止地址；
c. db f5022000+”偏移量” 可打出内存中的字符信息，获得module的信息；
注：Windbg中的module 名称通是不带后缀名的，如mscrt.dll库对应模块名为是mscrt。
加载指定模块的符号文件
Windbg对于符号文件的加载策略为延迟加载，也就是知道符号使用时才将符号加载到调试器，并进行解析。ld命令可打破延迟加载模式，立即将对应模块的符号加载到内存，命令格式：
ld 模块名称 [/f 符号名称]
Windbg加载的符号状态
调试器加载符号后，通过 lm命令能够看到加载的符号信息及符号加载的状态：
deffered–模块已经加载，符号尚未加载，将在需要时加载；
#–符号文件与可执行文件的时间戳和校验和信息均不匹配；
T–符号文件的时间戳信息丢失，值为0或未获取到；
C–符号文件的校验和信息对视，不可访问或值为0；
Export–未找到准确的符号文件，所以符号信息是从二进制可执行文件的到处表中提取出来的；
M–符号文件与可执行文件不匹配，时间戳或校验和。然而，由于符号配置等原因，符号文件已加载。
DML开关
DML–调试器标记语言，可以展现像html一样的链接，引导用户在点击链接时从一处跳转到另一处。通过如下命令可控制DML的开关状态：
.prefer_dml 1 // 开启DML
.prefer_dml 0 // 关闭DML.
符号验证技巧
如果对于已加载符号的准确性存在疑虑，可以通过一下步骤做验证：
1) !sym noisy 打开符号加载过程打印；
2) .reload /i ModuleName可以看到符号加载的完整过程，在符号加载完成后，如果有WARNING或ERROR的提示信息，意味着符号加载过程中出现了错误或者异常。
同时也可以借助汇编对已加载的符号做基本的校验：
u videoprt!videoportfindadapter2查看该函数符号对应的汇编指令，通常在函数起始位置的指令为:push ebp; mov ebp,esp;
One other useful technique for verifying symbols is unassembling code. Most functions begin with an add, sub, or push operation using either the base pointer (ebp) or the stack pointer (esp or sp). Try unassembling (U Function) some of the functions on the stack (from offset zero) to verify the symbols.
符号查找
通过x命令查找包含指定关键字的模块，参考：
1）x *main 2）模块内查找：x server!m*模块内查找m开头的符号
线程切换命令
~. 当前线程
~#切换到出现异常的线程
~*进程中的所有线程
~Number 切换到16进制编号的线程。通常线程编号的格式为[process_number].[thread_number]
~~[TID] 切换到指定线程编号的线程