简介
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
快速切换。switch clocktime 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捕获不到"C# Debug Message!"
是否勾选了对应的捕获选项。有时候最简单的反而是最容易被我们忽略的。
捕获选项
检查当前的
DebugView
实例的连接状态,注意看标题栏。通过标题栏查看连接状态
在
win10
系统中,无法捕获驱动程序输出的调试信息。首先,捕获驱动程序的调试信息,需要管理员权限,如果没有管理员权限,会报下图中的错误:
需要管理员权限
其次,从Vista
开始,需要设置注册表才能捕获。另存下面代码为Debug Print Filter.reg
,双击导入注册表后,重启生效。
Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
"DEFAULT"=dword:0000000f
注册表对应的内容如下图所示:
具体原因请参考 http://www.osronline.com/article.cfm%5eid=295.htm,为了方便大家,我截取了该网址的内容:
退出
DebugView
后,再次运行DebugView
捕获内核调试信息会报下图中的错误:unable to access dbgv.sys 从提示看,应该是
Dbgv.sys
被占用了。使用Process monitor
查看DebugView
的文件读写记录,印证了我们的猜测。dbgview-createfile-failed-event
本想通过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[1]
dbgview 在 windows 10 中关闭后再次打开时无法 "capture kernel"[2]
References:
[1] OSR: Getting DbgPrint Output To Appear In Vista and Later:
http://www.osronline.com/article.cfm%5eid=295.htm
[2] dbgview 在 windows 10 中关闭后再次打开时无法 "capture kernel":
https://www.cnblogs.com/jiaochen/p/5581440.html
欢迎留言交流