简介
DebugView
是sysinternals
工具集中的一款用来查看调试信息的工具。不管你是内核开发人员还是应用程序开发人员,都会用到这款神器。先简单看看DebugView
可以干什么吧。
- 可以查看应用程序输出的调试信息。
- 可以查看驱动程序输出的调试信息。
- 可以查看本地机器的调试信息。
- 可以查看远程机器的调试信息。
- 可以根据规则高亮显示。
- 可以根据关键字过滤。
- 可以根据关键字搜索。
- 可以自动显示最新一条记录。
- ……
功能太多太全了,有木有?!心动了吗? 快跟我一起来了解下这个神器吧。
如何输出调试信息
应用程序和驱动程序都可以通过对应的API
生成调试信息。
-
非托管应用程序可以通过
Win32 API
OutputDebugString()
输出调试信息。 -
托管应用程序可以通过
System.Diagnostics.Debug.Print()
输出调试信息,内部会调用OutputDebugString()
。 -
驱动程序可以通过
DbgPrint()
或DbgPrintEx()
(或者使用KdPrint
或KdPrintEx
宏)输出调试信息。这两个宏在Debug
版里会分别映射到DbgPrint()
或DbgPrintEx()
,在Release
版会映射为空。
下图是一个使用DebugView
捕获C++
程序和C#
程序输出的调试信息的截屏。
基本功能
DebugView
有一些值得我们了解的功能,下面列举了一些我用到的功能。
-
Options
->Show milliseconds
可以精确到毫秒,默认精确到秒。 -
Options
->Clock time
(快捷键CTRL + T
),可以切换时间显示方式。有时候我们希望知道两条调试信息的时间差(估算某段代码的执行效率的时候),有时候我们希望知道某条调试信息具体的时间点,可以按
CTRL + T
快速切换。 -
Edit
->Filter/Highlight...
可以过滤/高亮符合条件的记录。-
不相关的调试信息太多,看不过来怎么办?过滤功能可以帮助我们排除无用的调试信息。
-
所有记录都是黑白的,区分起来太费劲,关键调试信息不够醒目。怎么办?高亮功能可以高亮显示包含特定关键字的调试信息。
点开下面的视频感受下吧!
-
-
使用
File
->New Window...
可以快速启动DebugView
的新实例。如果你需要监听多台机器的调试信息,此功能可能对你有用。 -
使用
Computer
->Connect...
可以监视远程计算机的调试信息。- 远端机器上必须以代理模式运行
DebugView
。可以通过dbgview.exe /a
启动代理模式。更多选项,请参考DebugView
的帮助文档,或者运行dbgView.exe -h
查看。 - 以代理模式运行的
DebugView
会监听TCP 2020
端口,注意设置防火墙的例外规则。 DebugView
可以同时连接并监视多台远程计算机。可以通过Computer
->Disconnect
来断开与某台计算机的连接。- 当前连接的机器名会在标题栏显示,注意看标题栏。
- 远端机器上必须以代理模式运行
-
不要让多个
DebugView
同时监听同一台机器的调试信息,否则会导致调试信息分别发送到不同的DebugView
中,对我们排错产生不必要的干扰! -
DbgView.exe -h
可以查看DebugView
支持的命令行参数及简短介绍。
-
其它
-
F1
打开帮助文档。 -
CTRL + F
查找符合条件的调试信息。 -
F3
查看下一条查找到的记录。 -
CTRL + C
复制选中的记录。 -
CTRL + S
保存调试信息到文件中。 -
CTRL + X
清空所有的调试信息。 -
CTRL + A
开启或关闭自动滚屏。 -
……
-
-
更多功能,请参考《Windows Sysinternals 实战指南》。
如果遇到DebugView
不能捕获调试信息的情况,可以从以下几个方面排查:
问题及解决方法
-
如果应用程序正在被调试,那么
DebugView
捕获不到该程序的调试信息,请到调试器的输出窗口查看。具体原理可以参考张银奎老师的《软件调试》。
-
是否勾选了对应的捕获选项。有时候最简单的反而是最容易被我们忽略的。
-
检查当前的
DebugView
实例的连接状态,注意看标题栏。
-
在
win10
系统中,无法捕获驱动程序输出的调试信息。首先,捕获驱动程序的调试信息,需要管理员权限,如果没有管理员权限,会报下图中的错误:
其次,从Vista
之后,需要设置注册表才能捕获。另存下面代码为Debug Print Filter.reg
,双击即可。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerDebug Print Filter]
"DEFAULT"=dword:0000000f
注册表对应的内容如下图所示:
具体原因请参考 http://www.osronline.com/article.cfm^id=295.htm,为了方便大家,我截取了该网址的内容:
-
退出
DebugView
后,再次运行DebugView
捕获内核调试信息会报下图中的错误:从提示看,应该是
Dbgv.sys
被占用了。使用Process monitor
查看DebugView
的文件读写记录,印证了我们的猜测。
本想通过process explorer
的Find Handle or DLL
功能来查看是哪个进程在占用,**未果!**使用其它工具也没搜到相关信息。如果有哪位朋友知道如何查看驱动文件(*.sys
)的占用情况,请告诉我!
在网上搜到解决方案:只需要重命名Dbgv.sys
即可。参考网址:https://www.cnblogs.com/jiaochen/p/5581440.html
说明: 这应该是老版本的一个
bug
,我在微软官网上下载最新的4.9
版本的DebugView
后,没有此问题了。建议大家下载最新版的DebugView
使用。
广而告之
关于OutputDebugString()
的实现原理,可以参考 张银奎老师的 《软件调试》(第一版)第10
章 10.7
节 输出调试字符串。《软件调试》这本调试领域的扛鼎之作不用我多做介绍吧?买就对了!不过第一版已经绝版了,好消息是:《软件调试》(第二版)卷 1:硬件基础 已经出版了。而且听张老师说,年底的时候, 《软件调试》(第二版)卷 2 有望出版(不过看这意思,2019
年应该没戏了,希望2020
年上半年能等到),对调试感兴趣的朋友有福了,多多关注下吧。
对了,张老师也有公众号的,大家可以搜索格友
关注。
总结
-
使用
OutputDebugString()
可以方便的输出调试信息。如果你还没在你的程序里加上调试信息的话,快快加上吧。注意不要把敏感信息输出来,别人用工具可以方便的查看到。切记! -
DebugView
是调试的好帮手。过滤和高亮功能可以让我们更加有效的查看我们关心的调试信息。 -
《软件调试》详细讲述了
OutputDebugString()
的实现原理,感兴趣的小伙伴儿一定要看啊!
参考资料
- 《Windows Sysinternals 实战指南》
- 《软件调试》
- OSR: Getting DbgPrint Output To Appear In Vista and Later
- dbgview 在 windows 10 中关闭后再次打开时无法 capture kernel