windbg 查看结构体_用WinDbg进行调试

通往WinDbg的捷径(一)

windbg的使用详细:

http://wenku.baidu.com/view/f576c31e650e52ea55189832.html

导言

你钟情什么样的调试器?如果你问我这个问题,我会回答是“Visual Studio + WinDbg”。我比较喜欢Visual Studio那朴实无华且易操作的接口,更喜欢它能迅速把我需要的信息以可视的形式展示出来。但遗憾的是,Visual Studio调试器无法获取某些信息。例如,假设我想知道哪个线程正在占用特殊的临界区?或者是哪个函数占用了大部分的栈空间?不用担心,有WinDbg呢。它的命令能回答这些问题,以及调试过程中出现的其它有趣的问题。甚至不退出Visual Studio,WinDbg就可以附上目标应用程序――谢谢WinDbg支持入侵模式的调试(本文后面会详细讨论),我们可以把Visual Studio GUI和WinDbg的命令行结合起来使用。

唯一的问题是WinDbg不太好用。需要花些时间适应它的用户界面,而掌握它的命令则要花更多的时间。但是假设你现在就需要它,马上用它调试紧急的问题?有什么快速简便的方法吗?当然。WinDbg的小弟CDB,功能和WinDbg差不多;因为它是基于命令行的,所以用起来更简单一些。在这篇文章里,我将把CDB作为Visual Studio调试器的补充,介绍怎样使用CDB。在这篇文章里,你将会看到怎样配置CDB,怎样用它解决实际的问题。另外,我还会提供一些批处理文件,它们可以隐藏CDB命令行接口的大部分复杂性,也让你少打几个字。

安装与配置

安装

当然,在使用CDB前,必须先安装并配置它。WinDbg和CDB是Debugging Tools for Windows的一部分,可以从这里下载。安装很简单,你可以用默认设置安装,除非你准备用WinDbg SDK开发应用程序。(如果你准备用SDK,需要选择定制安装,并启用SDK安装;推荐你把它安装在不包含空格的目录名的目录中)。安装完成后,安装目录里将包含所有必需的文件,包括WinDbg(windbg.exe)和CDB(cdb.exe)。

调试工具也支持“xcopy”类型的安装。也就是说,在一台机器上安装后,如果你想在其它的机器上使用,不用再安装,直接把已经安装的目录直接拷过去就行了。

符号文件服务器路径

如果不能访问操作系统DLL的最新的符号文件,有些重要的WinDbg命令将不能正常工作。在以往,我们可以从微软的FTP服务器上下载巨大的符号文件包,然后从中找出需要的符号文件。这非常浪费时间,而且在操作系统更新或升级后,符号文件就过时了(因此也就变得毫无用处)。幸运的是,现在有更简便的方法来获得符号文件――符号文件服务器。WinDbg和Visual Studio都支持这个方法,在需要时直接从微软维护的服务上下载最新的符号文件。有了符号文件服务器,我们再也不用下载整个符号文件包了(那实在是太大了),因为调试器知道需要用到哪个DLLs,所以直接下载单个符号文件就行了。如果符号文件在操作系统更新或升级以后过时了,调试器会注意到这种情形,并再次下载必需的符号文件。

为了使符号文件服务器起作用,我们应该让调试器知道符号文件服务器的路径。最简单的方法是在_NT_SYMBOL_PATH环境变量里指定符号文件服务器的路径。可以用如下的路径:

"srv*c:\symbolcache*http://msdl.microsoft.com/download/symbols"

(c:\symbolcache目录将被用来保存从符号文件服务器下载下来的符号文件;当然,你可以用任何有效的本地或网络路径)。例如:

set _NT_SYMBOL_PATH=srv*c:\symbols*http://msdl.microsoft.com/download/symbols

在你设置_NT_SYMBOL_PATH环境变量之后,就可以使用符号文件服务器了。关于符号文件服务器的更多信息,相关设置,以及可能会用到的排除故障的小技巧,可以从WinDbg的文档中找到(Debuggers | Symbols section)。

如果你需要从一台需登录的代理服务器后访问符号文件服务器。参见本篇文章中CDB and proxy servers部分,以了解更多信息。

CDB 命令行基础介绍

启动调试会话

当我们使用新的调试器时,第一个问题通常是:怎样开始调试会话呢?像大多数调试器一样,CDB允许我们调试应用程序的新实例,或者附上一个已经运行的过程。启动新实例就象下面一样简单:

cdb c:\myapp.exe

如果我们想附上已经运行的过程,可能会用上下列某个选项:

----------------------------------------------------------------------------------------------------------------------

选项                描述                                                                            例子

----------------------------------------------------------------------------------------------------------------------

-p Pid              这个选项允许CDB附上指定进程ID的进程。可以用任务管理器或类似的工具得到进程ID。   cdb -p 1034

----------------------------------------------------------------------------------------------------------------------

-pn ExeName         这个选项允许CDB用指定的可执行文件名(.exe)附上进程。这个选项比“-p Pid”更

方便,因为我们通常知道执行的程序名,不必在任务管理器中寻找进程的ID。但是如果

多个进程使用同一个名字(CDB将报错),就不能用这个选项了。                       cdb -pn myapp.exe

----------------------------------------------------------------------------------------------------------------------

-psn ServiceName    这个选项允许CDB附上指定服务的进程。例如,假如你想附上Windows Management

Instrumentation服务,应该用WinMgmt作为服务名。                                  cdb -psn MyService

----------------------------------------------------------------------------------------------------------------------

CDB也可以分析故障转储。用-z选项打开故障转储:

cdb -z DumpFile

例如:

cdb -z c:\myapp.dmp

结束调试会话

启动新的调试会话后,CDB会显示它自己的命令行提示符。你可以在这个提示符下执行CDB支持的任何命令。

  

'q'命令结束调试会话并退出CDB:

0:000> q

quit:

>

警告:当你结束调试会话,退出CDB时,操作系统也将终止被调试的程序。如果你想退出CDB并保持被调试程序,可以用.detach命令(Windows XP或更新的操作系统才支持),或者用非入侵的模式(下面讨论)。

运行命令

虽然可以在CDB命令行提示符下执行调试器命令,但在命令行里指定需要的命令通常更快一些,用-c选项。

cdb -pn myapp.exe -c "command1;command2"

(用分号分隔多个命令)

例如,下列命令行将把CDB附上我们的应用程序,显示已加载的模块,然后退出:

cdb -pn myapp.exe -c "lm;q"

注意,在命令列表的结尾加上'q'命令――将在所有的调试器命令执行后关闭CDB。

入侵模式调试

在默认情况下,当我们用CDB调试一个已经运行的进程时,它通常作为全功能的调试器附上进程(使用Win32 Debugging API)。在这种模式下,可以设置断点,单步调试代码,得到各种调试事件的通知(例如,异常,加载/卸载模块,启动/退出线程,等等)。Visual Studio也可以做到这些,并提供更友好的用户界面。另外,每个进程每次只能被一个调试器附上。这是否意味着如果我们用Visual Studio调试器调试应用程序,就不能再用CDB得到它的附加信息了?不,不完全是这样,因为除了全功能调试模式外,CDB还支持入侵调试模式。

CDB以入侵模式附上目标进程时,并没有使用Win32 Debugging API,而是先暂停目标进程的所有线程,执行用户指定的命令。在所有的命令执行之后,CDB退出之前,恢复暂停的线程。因此,目标进程可以继续运行,好像什么事也没发生一样。即使像Visual Studio之类的全功能调试器正在调试目标进程,CDB仍可以用入侵模式附上它,并获得所需要的信息。在CDB完成任务并分离附上的进程后,我们可以继续用Visual Studio调试器调试这个应用程序。

怎么启用CDB的入侵模式?用-pv命令行选项。例如,下列命令行将以入侵模式附上应用程序,显示已加载模块的列表,然后退出。在CDB退出之后,应用程序将继续运行。

cdb -pv -pn myapp.exe -c "lm;q"

把输出内容保存到日志文件

有些CDB命令的输出内容可能会很长,从控制台窗口阅读十分不便。因此,把输出内容保存到日志文件,再用其它的编辑器查看会更好一些,CDB允许我们用-loga和-logo选项来实现('-loga '把输出内容追加到指定文件的结尾;而'-logo '将覆盖原有的文件,如果文件已经存在的话)。

在我们的例子命令(列出目标进程里的模块)里增加记录功能,把输出内容保存到当前目录的out.txt文件里:

cdb -pv -pn myapp.exe -logo out.txt -c "lm;q"

源行号信息

CDB支持的另外一个重要选项是-lines。这个选项打开源行号信息支持,例如,当报告调用栈时,允许CDB显示源文件及源行号。(在默认情况下,源行号支持是关闭的,CDB不显示源文件/行号信息)。

CDB 和代理服务器

如果你在需要登录的代理服务器后用CDB,在默认情况下,将不能访问符号文件服务器。原因是在默认配置下,当CDB尝试连接符号文件服务器时,不显示代理服务器的登录提示。为了更改这个行为,使我们可以访问符号文件服务器,需要在命令行之前加上两条命令:

!sym prompts;.reload

例如:

cdb -pv -pn myapp.exe -logo out.txt -c "!sym prompts;.reload;lm;q"

启动消息

当CDB调试新应用程序,附上已经存在的进程,或打开故障转储时,将显示一系列的启动消息。CBD命令(可以用-c选项指定,或手动输入)的输出内容跟在这些消息之后。通常情况下,启动消息只显示一些无关紧要信息;但是如果在执行时出错了,它将包含这个问题的描述,有时候也会提供解决方法。

例如,下列输出内容通知我们没有设置符号路径,因此,有些调试器命令不能工作:

D:\Progs\DbgTools>cdb myapp.exe

Microsoft (R) Windows Debugger  Version 6.5.0003.7

Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: myapp.exe

Symbol search path is: *** Invalid ***

****************************************************************************

* Symbol loading may be unreliable without a symbol search path.           *

* Use .symfix to have the debugger choose a symbol path.                   *

* After setting your symbol path, use .reload to refresh symbol locations. *

****************************************************************************

总结

这里是一些常见的CDB命令行模板,本篇文章的剩下部分将会用到它们(我们总是用同样的模板,然后根据我们要解决的问题,改变-c选项内部的命令行列表)。

用入侵模式附上运行的进程(通常是进程ID),执行一组命令,并把输出内容保存在out.txt文件里:

cdb -pv -p -logo out.txt -lines -c "command1;command2;...;commandN;q"

用入侵模式附上运行的进程(用可执行文件名),执行一组命令,并把输出内容保存在out.txt文件里:

cdb -pv -pn -logo out.txt -lines -c "command1;command2;...;commandN;q"

用入侵模式附上运行的进程(通常是服务名),执行一组命令,并把输出内容保存在out.txt文件里:

cdb -pv -psn -logo out.txt -lines -c "command1;command2;...;commandN;q"

打开故障转储文件,执行一组命令,并把输出内容保存在out.txt文件里:

cdb -z -logo out.txt -lines -c "command1;command2;...;commandN;q"

如果我们在需要登录的代理服务器后使用CDB,要访问符号文件服务器,需要增加两条命令。例如:

cdb -pv -pn -logo out.txt -lines -c "!sym prompts;.reload;command1;command2;...;commandN;q"

好像要打好多字?其实不是这样,稍后,我将提供一些批处理文件,它们将为我们隐藏重复

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值