windbg使用手册

WinDbg 命令三部曲:(一)WinDbg 命令手册 - sangmado - 博客园 (cnblogs.com)

WinDbg 命令三部曲:(一)WinDbg 命令手册

 

本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载。

系列博文

  1. 《WinDbg 命令三部曲:(一)WinDbg 命令手册》
  2. 《WinDbg 命令三部曲:(二)WinDbg SOS 扩展命令手册》
  3. 《WinDbg 命令三部曲:(三)WinDbg SOSEX 扩展命令手册》

导航目录

调试准备

为了测试 WinDbg 中使用 SOS 扩展命令,我创建了应用程序 "MemoryLeakApp.exe",Visual Studio 程序选择为 64 位环境编译。

 "MemoryLeakApp.exe" 启动运行后可能占用内存600M。

此时,选择使用 64 位 WinDbg 来调试程序。我们先通过 Attach Process 方式来调试。

当然,如果我们使用了 32 位的 WinDbg 去 Attach 进程,会直接报错。

 

WinDbg 常用命令手册

内置帮助命令
命令 描述
?

?             显示常规命令

? /D            通过 DML(Debugging Markup Language) 方式显示常规命令

.help

.help        显示 . 系列命令

.help /D       通过 DML 方式显示 . 系列命令

.help /D a*   通过 DML 方式显示所有以 'a' 字母开头的 . 系列命令

.chain

.chain          列出所有已加载的调试器扩展

.chain /D      通过 DML 方式列出所有已加载的调试器扩展

.extmatch

.extmatch /e ExtDLL FunctionFilter      显示调试器扩展的所有导出函数

.extmatch /D /e ExtDLL FunctionFilter  通过 DML 方式显示调试器扩展所有导出函数

.extmatch /D /e uext *                       显示 uext 扩展中的所有导出函数

.hh

.hh         打开 WinDbg 的帮助文件

.hh Text  打开 WinDbg 的帮助文件,并自动搜索 Text 的内容

.hh dt     在 WinDbg 帮助文件中搜索 dt 命令

调试会话命令
命令 描述
.attach

.attach PID 附加到指定ID的进程

.detach

.detach      结束调试会话,被调试进程仍可继续运行

q

q               结束调试会话,同时终止被调试进程的进行

qq             结束调试会话,同时终止被调试进程的进行

.restart

.restart      重启被调试应用

一般信息命令
命令 描述
version

显示调试器版本信息和已加载的调试器扩展

vercommand

显示调试器启动文件的路径

vertarget

显示目标机器的版本

CTRL+ALT+V

打开或关闭 Verbose 模式开关,某些命令在此模式下可以给出更多详细信息

.formats

.formats Expression  显示数字的各种格式信息

.formats 5

.cls

清理屏幕

.last event 显示最新的异常信息或事件信息
.effmach

.effmach 显示有效作用的机器信息
.effmach .
.effmach #
.effmach x86 | amd64 | ia64 | ebc

.time

显示系统记录的各种时间

.echo

.echo String  输出字符串

.echo "String"

.echo "Hello World"

符号加载命令
命令 描述
ld

ld ModuleName  加载指定模块的符号

ld *                  加载所有模块的符号

!sym

!sym                获取符号加载状态

!sym noisy       让调试器显示符号搜索详细信息

!sym quiet        默认项,不显示符号搜索信息

.sympath

.sympath         显示和设置符号搜索路径

.sympath+       增加符号搜索路径

.sympath+ C:\Symbols

.symopt

.symopt            显示当前符号可选项

.symopt+ Flags  添加符号可选项

.symopt- Flags   移除符号可选项

.symfix

.symfix                           设置符号库路径

.sym+ DownstreamStore  添加符号库路径

x

x [Options] Module!Symbol    模式匹配符号信息

x /t ..            根据数据类型匹配

x /v ..            显示详细信息

x /a ..            按照地址排序

x /n ..            按照名称排序

x /z ..            按照大小排序

x *!               列出所有模块

x ntdll!*          列出 ntdll 模块

x /t /v ntdll!*    列出 ntdll 模块数据类型和符号类型

.reload

.reload                            重新加载符号信息

.reload [/f | /v]                /f 强制立即加载符号 /v 显示详细信息

.reload [/f | /v] Module     Module 为指定模块加载符号信息

.reload /f @"ntdll.dll"

.reload /f @"C:\WINNT\System32\verifier.dll"

模块加载命令
命令 描述
 lm

lm[ v | l | k | u | f ] [m Pattern] 显示已加载的模块

lm   显示所有加载和未加载的模块信息

lmv 显示已加载模块的详细信息

lml  同时显示加载的符号信息

lmk 显示内核模块信息

lmu 显示用户模块信息

lmf  显示镜像路径

lmm 匹配模块名称

lmD 使用 DML 方式显示

lmv m kernel32 显示 kernel32 模块详细信息

!dlls

!dlls         列出所有加载的模块和加载数量

!dlls -i      根据初始化顺序

!dlls -l      根据加载顺序(默认项)

!dlls -m    根据内存顺序

!dlls -v     显示更多详细信息

!dlls -c ModuleAddr  仅显示 ModuleAddr 地址的模块信息

!dlls -?     显示帮助

!dlls -v -c kernel32 显示 kernel32.dll 的信息

!lmi

!lmi Module    显示模块的详细信息,包括加载符号信息

!lmi kernel32  显示 kernel32.dll 模块的信息

异常分析命令
命令 描述
!analyze

!analyze -v       显示当前异常的详细信息

!analyze -hang  诊断线程调用栈上是否有任何线程阻塞了其他线程

!analyze -f        查看异常分析信息,尽管调试器并未诊断出异常

进程信息命令
命令 描述
!dml_proc

通过 DML 方式显示当前进程的信息

.tlist

显示当前所有进程

线程信息命令
命令 描述
~

~                              显示线程信息

~* [Command]           所有线程

~. [Command]            当前线程

~# [Command]           引发当前事件或异常的线程

~Number [Command]  显示指定序号的线程

~~[TID] [Command]   显示指定线程ID的线程

~Ns                          切换到线程 N

~* k  显示所有线程的调用栈

~2 f   冻结2号线程

~# f  冻结引发异常的线程

~3 u  解除对3号线程的冻结

~2 k  显示2号线程的调用栈

~e

~* e CommandString            在所有线程上执行命令

~. e CommandString             在当前线程上执行命令

~# e CommandString            在引发异常的线程上执行命令

~Number e CommandString   在指定序号的线程上执行命令

~2e r; k; kd  相当于 ~2r; ~2k; ~2kd

~*e !gle       显示所有线程的最后一个错误信息

~f

~Thread f    冻结线程

~u

~Thread u   解除冻结线程

~n

~Thread n   挂起线程,增加线程挂起数量

~m

~Thread m  恢复线程,减少线程挂起数量

!teb

显示线程环境信息

!tls 

!tls -1          -1 为显示当前线程所有的 slot 信息

!tls SlotIdx   显示指定的 slot 信息

!tls [-1 | SlotIdx] TebAddr

.ttime

显示线程时间信息

!runaway

[Flags: 0 | 1 | 2] 显示每个线程消耗的时间,用于快速的查找 CPU 时间消耗最多的线程

0 用户态时间

1 内核态时间

2 自线程创建起的时间间隔

!gle

!gle         显示当前线程的最后错误

!gle -all    显示所有线程的最后错误

!error

!error ErrValue      解析错误信息

!error ErrValue 1   将错误值作为 NTSTATUS 代码

堆栈信息命令
命令 描述
k

k [n] [f] [L] [#Frames]  显示调用栈信息

kn      调用栈包含帧号

kf       临近帧的距离

kL       忽略源代码

kb ...  最开始的 3 参数

kp ...  所有的参数,包括参数类型、名称和值

kP ...  所有的参数

kv ...  FPO信息

kb 5   显示最开始的 5 个帧

kd

kd [WordCnt]  显示原始栈数据和可能的符号信息

kM

使用 DML 格式显示堆栈信息

.kframes

设置栈长度,默认是20(0x14)

.frame

.frame            显示当前帧

.frame #         指定帧号

.frame /r [#]   显示寄存器信息

.frame 2         显示帧号 2 的信息

.frame /r 0d    显示 0 帧中寄存器信息

!uniqstack

!uniqstack                   显示所有线程的栈信息

!uniqstack [b|v|p] [n]   b=前3个参数;v=FPO信息;p=所有参数;n=帧号

!uniqstack -?               显示帮助

!findstack

!findstack Symbol              找到包含符号或模块的栈

!findstack Symbol [0|1|2]   0=仅显示线程ID;1=线程ID和帧;2=全部的线程栈;

!findstack -?                      显示帮助

!findstack clr 2                   显示包含 clr 的所有栈的信息

扩展帮助命令
命令 描述

!Ext.help

常规扩展命令帮助

!Exts.help

 

!Uext.help

用户态模式扩展命令帮助

!Ntsdexts.help

用户态扩展命令帮助(OS相关)

!logexts.help

日志相关扩展

!clr10\sos.help

调试托管代码

!wow64exts.help

wow64调试器扩展

!Wdfkd.help

内核态驱动框架扩展

!Gdikdx.help

图形驱动扩展

!NAME.help

显示任何 NAME 名称的扩展命令的帮助
日志扩展命令
命令 描述

!logexts.help

 显示所有日志扩展命令

!loge

!loge [dir]  打开日志功能,可选配置输出目录

!logi

初始化日志功能

!logd

关闭日志功能

!logo

!logo                    列出日志配置信息

!logo [e|d] [d|t|v]  打开或关闭日志,d=调试器,t=文本文件,v=详细信息

!logc

!logc                        列出所有日志类型

!logc p #                  列出 # 中的日志类型

!logc [e|d] *              打开或关闭所有日志类型

!logc [e|d] # [#] [#]  打开或关闭日志类型 #

!logb

!logb p  打印缓冲区信息至调试器

!logb f   刷新缓冲区内容之日志文件

!logm

!logm                          显示模块的包含或屏蔽列表

!logm [i|x] [DLL] [DLL]  指定模块的包含或屏蔽列表

参考资料

本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载。

系列博文

  1. 《WinDbg 命令三部曲:(一)WinDbg 命令手册》
  2. 《WinDbg 命令三部曲:(二)WinDbg SOS 扩展命令手册》
  3. 《WinDbg 命令三部曲:(三)WinDbg SOSEX 扩展命令手册》
 
标签: .NETWinDbgSOSSOSEX
 
posted @ 2014-02-06 10:14  sangmado  阅读(50312)  评论(30)  编辑  收藏  举报
 

 
必须学习啊、。
#2楼[楼主2014-02-06 21:22 sangmado
@ 规格严格-功夫到家
引用必须学习啊、。


我也是学习。
#3楼2014-02-07 09:44 Hunt
楼主博文风格不错。
我在做一个边锋游戏的记牌器。
我可否使用该工具查找游戏的内存信息?
想从内存中读取牌的信息。请问该思路是否合适。
#4楼2014-02-07 10:15 DiggingDeeply
good post.
#5楼[楼主2014-02-07 10:55 sangmado
@ Hunt
引用楼主博文风格不错。我在做一个边锋游戏的记牌器。
我可否使用该工具查找游戏的内存信息?
想从内存中读取牌的信息。请问该思路是否合适。


你这是外挂的节奏吗?
我也不知道怎么做,提供一个链接不知道是否有用,描述实现WinDbg扩展的。
https://github.com/suwatch/cfexts
感谢分享
#7楼2014-02-07 14:07 骑马找驴
好文得收藏!lz恭喜发财~~
#8楼2014-02-07 14:32 通用C#系统架构
这个真是技术!
#9楼[楼主2014-02-07 15:29 sangmado
@骑马找驴
引用好文得收藏!lz恭喜发财~~


新年快乐,恭喜发财~~~
#10楼2014-02-07 16:44 ethan zhang
楼主不错啊,非常感谢,现在windbg越来越重要了
#11楼2014-02-07 17:07 Oline.Agile
好文啊,必须学习。
#12楼[楼主2014-02-07 17:48 sangmado
@ Oline.Agile
@ethan zhang
@通用C#系统架构
@骑马找驴
@john23.net
@DiggingDeeply
@Hunt
@规格严格-功夫到家

感谢各位园友的支持。
#13楼2014-02-07 23:14 花儿笑弯了腰
赞的
#14楼2014-02-08 09:10 Alvin
非常牛叉,赞一个
#15楼[楼主2014-02-08 10:57 sangmado
@ Alvin
引用非常牛叉,赞一个


翻译个命令不牛叉,只是让生活更美好。
#16楼[楼主2014-02-08 10:57 sangmado
@ 花儿笑弯了腰
感谢支持。
#17楼2014-02-08 17:35 Supper_litt
不明觉厉。
#18楼2014-02-10 11:00 ItsBird
膜拜大神,mark~
#19楼2014-02-10 11:01 Alberl
膜拜大神,mark~
#20楼[楼主2014-02-10 20:37 sangmado
@ Mort_1990
@ItsBird
@Alberl
感谢各位的支持。
#21楼2014-02-20 18:02 咖喱gg
希望有更多的调试技巧,比如查找锁死,查看哪里的代码占用过多性能
#22楼[楼主2014-03-18 20:26 sangmado
博文《WinDbg 命令三部曲》,今天在百度和Google分别搜索了下,就知道百度更懂中文是扯淡了,结论就是Google更懂搜索。http://t.cn/zHu9WHi
#23楼2014-03-30 11:13 永远的阿哲
这么好的文章,居然没有人顶?!
#24楼[楼主2014-03-30 15:13 sangmado
@ 永远的阿哲
引用这么好的文章,居然没有人顶?!

感谢支持
#25楼2014-07-01 15:49 子清
例子的程序有吗,谢谢
#26楼[楼主2014-07-01 16:04 sangmado
@ 子清
引用例子的程序有吗,谢谢


找不到了,其实和 "那些年黑了你的微软BUG" 文中的例子差不多,就是主动创造一个内存泄漏。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private static void BuildFruitTree(Tree fruitTree, int leafCount)
{
  Console.WriteLine("Building {0} ...", fruitTree.Name);
 
  for (int i = 0; i < leafCount; i++) // size M
  {
    Leaf<byte[]> leaf = new Leaf<byte[]>(Guid.NewGuid())
    {
      Content = CreateContentSizeOfOneMegabyte()
    };
    fruitTree.Leaves.Add(leaf);
  }
}
 
private static byte[] CreateContentSizeOfOneMegabyte()
{
  byte[] content = new byte[1024 * 1024]; // 1 M
  for (int j = 0; j < content.Length; j++)
  {
    content[j] = 127;
  }
  return content;
}
#27楼2017-03-18 04:32 经伟
正好需要,很有用
#28楼2017-03-29 09:40 rana4504
赞一个,学习中
#30楼2022-10-16 12:35 阿布5231

这个必须mark一下

 
 
 
posted @ 2023-02-27 16:16  黄立明02  阅读(50)  评论(0编辑  收藏  举报