38

你知道怎么使用DebugView查看调试信息吗?

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA%3D%3D&%3Bmid=2654077135&%3Bidx=8&%3Bsn=1c85227b7d12846727fe3f51c554708d
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

简介

DebugViewsysinternals 工具集中的一款用来查看调试信息的工具。不管你是内核开发人员还是应用程序开发人员,都会用到这款神器。先简单看看 DebugView 可以干什么吧。

  • 可以查看应用程序输出的调试信息。

  • 可以查看驱动程序输出的调试信息。

  • 可以查看本地机器的调试信息。

  • 可以查看远程机器的调试信息。

  • 可以根据规则 高亮显示

  • 可以根据关键字 过滤

  • 可以根据关键字 搜索

  • 可以自动显示最新一条记录。

  • ……

功能太多太全了,有木有?心动了吗?快跟我一起来了解下这个神器吧。

如何输出调试信息

应用程序和驱动程序都可以通过对应的 API 生成调试信息。

  • 非托管应用程序可以通过 Win32 API OutputDebugString() 输出调试信息。

  • 托管应用程序可以通过 System.Diagnostics.Debug.Print() 输出调试信息,内部会调用 OutputDebugString()

  • 驱动程序可以通过 DbgPrint()DbgPrintEx() (或者使用 KdPrintKdPrintEx 宏)输出调试信息。这两个宏在 Debug 版里会分别映射到 DbgPrint()DbgPrintEx() ,在 Release 版会映射为空。

下图是一个使用 DebugView 捕获 C++ 程序和 C# 程序输出的调试信息的截屏。

640?wx_fmt=png示例

基本功能

DebugView 有一些值得我们了解的功能,下面列举了一些我用到的功能。

  • Options -> Show milliseconds 可以精确到毫秒,默认精确到秒。

  • Options -> Clock time (快捷键 CTRL + T ),可以切换时间显示方式。

    有时候我们希望知道两条调试信息的时间差(估算某段代码的执行效率的时候),有时候我们希望知道某条调试信息具体的时间点,可以按 CTRL + T 快速切换。

    640?wx_fmt=gifswitch clocktime
  • Edit -> Filter/Highlight... 可以 过滤 / 高亮 符合条件的记录。

    • 不相关的调试信息太多,看不过来怎么办?过滤功能可以帮助我们排除无用的调试信息。

    • 所有记录都是黑白的,区分起来太费劲,关键调试信息不够醒目。怎么办? 高亮 功能可以高亮显示包含特定关键字的调试信息。

点开下面的视频感受下吧!

过滤/高亮功能

  • 使用 File -> New Window... 可以快速启动 DebugView 的新实例。如果你需要监听多台机器的调试信息,此功能可能对你有用。

  • 使用 Computer -> Connect... 可以监视远程计算机的调试信息。

    640?wx_fmt=gif监视远程机器的调试日志

使用此功能,需要注意以下事项:

    • 远端机器上必须以代理模式运行 DebugView 。可以通过 dbgview.exe /a 启动代理模式。更多选项,请参考 DebugView 的帮助文档,或者运行 dbgView.exe -h 查看。
    • 以代理模式运行的 DebugView 会监听 TCP 2020 端口,注意设置防火墙的例外规则。
    • DebugView 可以同时连接并监视多台远程计算机。可以通过 Computer -> Disconnect 来断开与某台计算机的连接。
    • 当前连接的机器名会在标题栏显示,注意看标题栏。

  • 不要让多个 DebugView 同时监听同一台机器的调试信息,否则会导致调试信息分别发送到不同的 DebugView 中,对我们排错产生不必要的干扰!

  • dbgView.exe -h 可以查看 DebugView 支持的命令行参数及简短介绍。

    640?wx_fmt=jpeg命令行选项
  • 其它

    • F1 打开帮助文档。

    • CTRL + F 查找符合条件的调试信息。

    • F3 查看下一条查找到的记录。

    • CTRL + C 复制选中的记录。

    • CTRL + S 保存调试信息到文件中。

    • CTRL + X 清空所有的调试信息。

    • CTRL + A 开启或关闭自动滚屏。

    • ……

  • 更多功能,请参考《Windows Sysinternals 实战指南》。

如果遇到 DebugView 不能捕获调试信息的情况,可以从以下几个方面排查:

问题及解决方法

  • 如果应用程序正在被调试,那么 DebugView 捕获不到该程序的调试信息,请到调试器的输出窗口查看。具体原理可以参考张银奎老师的《软件调试》。

    640?wx_fmt=gif DebugView捕获不到"C# Debug Message! "
  • 是否勾选了对应的捕获选项。有时候最简单的反而是最容易被我们忽略的。

    640?wx_fmt=png捕获选项
  • 检查当前的 DebugView 实例的连接状态,注意看标题栏。

    640?wx_fmt=png通过标题栏查看连接状态
  • win10 系统中,无法捕获驱动程序输出的调试信息。

    首先,捕获驱动程序的调试信息,需要管理员权限,如果没有管理员权限,会报下图中的错误:

    640?wx_fmt=png需要管理员权限

其次,从 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

注册表对应的内容如下图所示: 640?wx_fmt=png

具体原因请参考 http://www.osronline.com/article.cfm%5eid=295.htm,为了方便大家,我截取了该网址的内容: 640?wx_fmt=png

  • 退出 DebugView 后,再次运行 DebugView 捕获内核调试信息会报下图中的错误:

    640?wx_fmt=pngunable to access dbgv.sys

    从提示看,应该是 Dbgv.sys 被占用了。使用 Process monitor 查看 DebugView 的文件读写记录,印证了我们的猜测。

    640?wx_fmt=pngdbgview-createfile-failed-event

本想通过 process explorerFind Handle or DLL 功能来查看是哪个进程在占用,未果!使用其它工具也没搜到相关信息。如果有哪位朋友知道如何查看驱动文件( *.sys )的占用情况,请告诉我!

640?wx_fmt=pngno-search-result-of-dbgv

在网上搜到解决方案: 只需要重命名 Dbgv.sys 即可 。参考网址:https://www.cnblogs.com/jiaochen/p/5581440.html

说明:这应该是老版本的一个 bug ,我在微软官网上下载最新的 4.9 版本的 DebugView 后,没有此问题了。建议大家下载最新版的 DebugView 使用。

广而告之

关于 OutputDebugString() 的实现原理,可以参考 张银奎老师的 《软件调试》(第一版)第 1010.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

640?wx_fmt=jpeg

欢迎留言交流


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK