Visual Studio调试器指南---实时调试
在运行于 Visual Studio 之外的应用程序中发生异常或崩溃时,实时调试会自动启用 Visual Studio。 这样,您便可以在 Visual Studio 没有运行时测试应用程序,并在出现问题时利用 Visual Studio 开始调试。
实时调试不适用于在可视化工具等本机应用程序中承载的托管代码。 如果您在 Windows Server 2003 或 Windows 2000 SP3(或更高版本)中安装 .NET Framework,那么,只有在计算机重新启动后,才可以对在终端服务会话中通过受限用户帐户运行的进程使用实时调试。
使用实时调试
默认情况下,安装 Visual Studio 时会启用实时调试。启用实时调试之后,您可以在 Visual Studio 之外调试应用程序。 如果发生崩溃或异常,将会出现一个对话框,其中显示一条与下面类似的消息:在 terrarium.exe[3384] 中发生未经处理的异常(“System.TypeInitializationException”)
如果出现此对话框,您可以通过以下步骤开始调试。
发生错误时开始实时调试
在“实时调试”对话框中,在“可能的调试器”列表中,单击“Visual Studio 新实例”或单击已在运行的 Visual Studio 2010。
若要在以后发生崩溃时都自动使用 Visual Studio,请单击“将当前选定的调试器设置为默认调试器”。
如果要选择能够调试的代码类型,请单击“手动选择调试引擎”。 如果没有选择此选项,Visual Studio 将根据程序中的代码类型自动选择合适的调试引擎。
单击“确定”。
如果在您的应用程序中,某个程序集包含不受信任的代码,则会出现一个对话框以及一条安全警告。 此对话框使可以决定是否继续调试。 在继续调试之前,请决定您是否信任相应代码。 代码是您自己编写的吗? 您是否信任代码编写者? 如果该应用程序正在远程计算机上运行,您是否认识进程的名称? 即便该应用程序在本地运行,也不一定表示它是可信的应用程序。 例如,在 Internet Explorer 中可能会有恶意 ActiveX 控件运行。 请考虑此类恶意代码在您的计算机中运行的可能性。 如果您确信待调试代码值得信任,请单击“调试”。 否则,请单击“不调试”。
启用或禁用实时调试
您可以在“选项”对话框中启用或禁用实时调试。
启用或禁用实时调试
在“工具”菜单上,单击“选项”。
在“选项”对话框中选择“调试”文件夹。
在“调试”文件夹中选择“实时”页。
在“启用这些代码类型的实时调试”框中,选中或清除相关的程序类型:“托管”、“本机”或“脚本”。
要在启用实时调试后禁用它,必须使用管理员特权运行。 启用实时调试会设置一个注册表项,需要管理员特权才可以更改该项。
单击“确定”。
默认情况下,Windows 窗体应用程序有一个顶级的异常处理程序,该处理程序允许程序在能够恢复时继续运行。 因此,若要启用 Windows 窗体应用程序的实时调试,还必须执行下列步骤。
为 Windows 窗体启用实时调试
在 machine.config 或应用程序.exe.config 文件的 system.windows.form 节中,将 jitDebugging 值设置为 true。
<configuration> <system.windows.forms jitDebugging="true" /> </configuration>
在 C++ Windows 窗体应用程序中,还必须在 .config 文件或您的代码中设置 DebuggableAttribute。 如果在编译时使用 /Zi 而没有使用 /Og,则编译器会替您设置此特性。 然而,如果您想要调试非优化发布版本,则必须自行设置此项。 为此,您可以在应用程序的 AssemblyInfo.cpp 文件中添加下面一行:
[assembly:System::Diagnostics::DebuggableAttribute(true, true)];
即便在您的计算机中不再安装有 Visual Studio,仍可启用实时调试。 如果没有安装 Visual Studio,则不能在 Visual Studio“选项”对话框中禁用实时调试。 对于这种情况,您可以通过编辑 Windows 注册表来禁用实时调试。
通过编辑注册表禁用实时调试
在“开始”菜单中,单击“运行”。
在“运行”对话框中,键入 regedit,然后单击“确定”。
在“注册表编辑器”窗口中,找到并删除下列注册表项:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger
如果您的计算机运行的是 64 位操作系统,还请删除下列注册表项:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\DbgManagedDebugger
注意不要意外删除或更改任何其他注册表项。
关闭“注册表编辑器”窗口。
实时调试错误
您可能会遇到与实时调试相关联的下列错误消息。
<程序> 中发生未处理的 win32 异常。对此异常的实时调试失败,错误为: 登录用户没有调试崩溃应用程序的权限。
此信息指出:由于您没有正确的访问权限,实时调试失败。
无法附加到崩溃进程。 指定的程序不是 Windows 或 MS-DOS 程序。
当您尝试附加到 Windows 2000 下作为另一个用户运行的进程时会发生该错误。
若要解决此问题,请启动 Visual Studio,从“调试”菜单打开“附加到进程”对话框,然后在“可用进程”列表中找到您要调试的进程。 如果您不知道进程名称,请查看“Visual Studio 实时调试器”对话框并记下进程 ID。 在“可用进程”列表中选择该进程并单击“附加”。 在“Visual Studio 实时调试器”对话框中单击“否”以关闭该对话框。
未能启动调试器,因为没有用户登录。
在没有用户登录到控制台的计算机中,如果实时调试尝试启动 Visual Studio,则会发生此错误。 因为没有用户登录,所以没有用户会话来显示“实时调试”对话框。
要解决此问题,请登录到计算机。
类没有注册。
此错误指出:调试器尝试创建一个可能是因为安装问题而没有注册的 COM 类。
若要解决此问题,请使用安装盘重新安装或修复 Visual Studio 安装。
Visual Studio调试器指南---自动启动调试器
有时,可能需要调试由另一个进程启动的应用程序的启动代码。 这样的示例包括服务和自定义设置操作。 在这些情况下,可以让调试器在应用程序启动时启动并自动附加。
设置应用程序以自动启动调试器
启动注册表编辑器 (regedit)。
在“注册表编辑器”中打开 HKEY_LOCAL_MACHINE 文件夹。
定位到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options。
在“Image File Execution Options”文件夹中,找到要调试的应用程序的名称,如 myapp.exe。 如果无法找到要调试的应用程序:
右击“Image File Execution Options”文件夹,在快捷菜单上单击“新建项”。
右击新项,然后在快捷菜单上单击“重命名”。
将项名编辑成您的应用程序的名称;在本示例中为 myapp.exe。
右击 myapp.exe 文件夹,在快捷菜单上单击“新建字符串值”。
右击新的字符串值,然后在快捷菜单上单击“重命名”。
将名称更改为 debugger。
右击新的字符串值,并在快捷菜单上单击“修改”。
即显示“编辑字符串”对话框。
在“数值数据”框中,键入 vsjitdebugger.exe。
单击“确定”。
在“注册表”菜单中,单击“退出”。
包含 vsjitdebugger.exe 的目录必须位于系统路径中。 要将其添加到系统路径,请执行下列步骤:
以经典视图打开“控制面板”,并双击“系统”。
单击“高级系统设置”。
在“系统属性”中,单击“高级”选项卡。
在“高级”选项卡上,单击“环境变量”。
在“环境变量”对话框中的“系统变量”下,选择“路径”,然后单击“编辑”按钮。
在“编辑系统变量”对话框中,将该目录添加到“变量值”框中。 使用分号将它与列表中的其他项隔开。
单击“确定”关闭“编辑系统变量”对话框。
单击“确定”关闭“环境变量”对话框。
单击“确定”关闭“系统属性”对话框。
现在,使用任意方法启动该应用程序。 Visual Studio 将启动并加载该应用程序。
Visual Studio调试器指南---转储文件
转储文件(以前称为故障转储)使您能保存程序信息以供以后进行调试。 在没有源文件或符号文件的计算机上测试程序时,转储文件尤其有用。 发生崩溃时,可以先保存转储文件,以后在生成计算机或另一台具有源文件和调试符号的计算机上对其进行调试。
由 Visual Studio 保存和打开的转储文件使用名为小型转储的文件格式。 Visual Studio 可以保存附带或不附带堆信息的小型转储文件。Visual Studio调试器可以保存适用于托管代码或本机代码的小型转储文件。调试器可以加载由 Visual Studio 或由其他以小型转储格式保存文件的程序所创建的转储文件。
创建转储文件
创建和保存转储文件的方法有以下几种:
在 Visual Studio中调试进程时,可以使用“调试”菜单上的“将转储另存为”选项保存转储文件。
如果启用了实时调试,则可以附加到在调试器外部运行的故障进程,中断该进程,然后保存转储文件。
您可以保存使用 UserDump 实用工具创建的转储文件,该工具是 OEM 支持工具包的一部分。 可以从 Microsoft 网站的以下网页下载包的副本:http://www.microsoft.com/downloads/search.aspx?displaylang=zh-cn。
http://download.microsoft.com/download/win2000srv/Utility/3.0/NT45/EN-US/Oem3sr2.zip
您可以保存使用 Autodump+ 实用工具创建的转储文件,该工具是 Microsoft Windows 调试工具的一部分。 可以从 Microsoft 网站的以下网页下载 Windows 调试工具:Windows Hardware Developer Central(Windows 硬件开发中心)。
调试转储
Visual Studio 调试器可以读取包含有关托管代码、非托管代码或二者混合的信息的转储文件。 可以使用普通的调试窗口来同时调试本机转储和托管转储。
转储要求和限制
调试转储文件时,您进行调试的计算机必须能够访问该程序的 PDB 符号文件和二进制文件。 Visual Studio 可以处理某些模块缺少二进制文件的情况,但是必须具有足够的模块以生成有效调用堆栈的二进制。 否则,“模块”窗口中将显示消息“找不到匹配的二进制数”。
对于使用堆保存的小型转储文件,即使未找到应用程序的二进制文件,Visual Studio 也可以加载符号。 小型转储文件,没有需要二进制数以加载符号的堆。 但是,不包含堆的小型转储文件要小得多,如果您有存储或带宽限制,这可以是一个重要的考虑因素。
在 Visual Studio 中,可以使用调试窗口来同时调试本机和托管转储文件。Visual Studio 2008 不支持在调试器窗口中调试托管的代码。 调试托管的小型转储文件需要一个名为 SOS,从“即时”窗口中运行的工具。 在 Visual Studio 中,不再需要 SOS 来调试托管的小型转储文件。
保存和打开转储文件
在 Visual Studio 中,您可以保存来自本机进程或托管进程的转储文件,以便将来再进行调试。 您也可以加载从 Visual Studio 或其他生成转储的实用工具创建的转储文件。
保存转储文件
在“调试”菜单上,单击“将转储另存为”。
在“将转储另存为”对话框中,从“保存类型”列表中选择“小型转储”或者“附带堆信息的小型转储”。
“附带堆信息的小型转储”是 Visual Studio 使用的默认转储格式。 “小型转储”提供的信息较少,但同时需要的空间也较少。
使用导航控件选择保存位置。
单击“保存”。
如果正在调试托管代码,则“将转储另存为”会创建一个托管代码小型转储文件。 如果正在调试本机代码,则“将转储另存为”会创建一个本机代码小型转储文件。 如果正在调试混合的托管代码和本机代码,则“将转储另存为”会创建一个托管代码小型转储文件。
打开转储文件
在“文件”菜单上,单击“打开”,再单击“文件”。
在“打开文件”对话框中定位并选择转储文件。
它通常具有 .dmp 扩展名。
- 或者在“文件”菜单上,单击“打开”,再单击“文件”。
单击“确定”。
将显示“转储文件摘要”窗口。 在该窗口中,您可以查看转储文件的调试摘要信息、设置符号路径、启动调试以及将摘要信息复制到剪贴板中。
在“操作”部分中,单击“使用‘仅限本机’进行调试”或“使用‘混合模式’进行调试”开始调试。
为了找到调试转储文件时所需的二进制文件,Visual Studio 会在符号搜索路径中进行查找。 为了确保 Visual Studio 能够找到这些二进制文件,您可以在“选项”对话框或“模块”窗口中添加一个符号搜索路径。
转储模块加载
当您在 Visual Studio 中加载转储文件时,调试器从转储文件所在位置开始查找模块。假设在您创建转储文件时加载了以下二进制文件和模块:
D:\qa\exmpl\exmpl.exe
D:\qa\exmpl\dll.dll
F:\win2k\system32\ntdll.dlll
F:\win2k\system32\kernel32.dll
Visual Studio调试器指南---断点和跟踪点
断点告诉调试器应用程序应该在某个点中断或暂停执行。当中断发生时,程序和调试器被称为处于中断模式。跟踪点是Visual Studio中的一个新调试器功能。跟踪点是具有与其关联的自定义操作的断点。当命中跟踪点时,调试器将执行指定的跟踪点操作,而不是中断程序执行。跟踪点的一个常见用途是在程序到达某个点时打印消息。您可以将跟踪点用于许多与使用跟踪相同的目的,但无需修改代码。另一个区别是,跟踪点只在调试器下运行时工作。
断点概述
断点标志符号
源窗口和反汇编窗口通过在左边距中显示名为glyph的符号来显示断点位置。下表描述了这些标志符号。如果将鼠标放在断点图示符上,则会出现一个断点提示,其中包含更多信息。此信息对于错误和警告断点特别有用。
Glyph |
Description |
---|---|
正常断点。实心标志符号表示断点已启用。空心标志符号表示它已被禁用。 |
|
高级断点。激活/禁用。符号+表示断点至少附加了一个高级功能(如条件、命中计数或筛选器)。 |
|
映射断点。激活/禁用。断点在ASP/ASP.NET代码中设置并映射到相应HTML页面中的断点,或者在服务器端脚本文件中设置并映射到相应的客户端脚本文件。 |
|
追踪点。激活/禁用。达到此点将执行指定的操作,但不会中断程序执行。 |
|
高级跟踪点。激活/禁用。符号+表示跟踪点至少附加了一个高级功能(如条件、命中计数或筛选器)。 |
|
映射跟踪点。激活/禁用。跟踪点在ASP/ASP.NET代码中设置,并映射到相应HTML页面中的跟踪点。 |
|
断点或跟踪点错误。X表示由于错误条件,无法设置断点或跟踪点。 |
|
断点或跟踪点警告。感叹号表示由于临时条件,无法设置断点或跟踪点。通常,这意味着断点或跟踪点位置的代码尚未加载。如果附加到进程并且未加载该进程的符号,则也可以看到。加载代码或符号时,将启用断点并更改图示符 |
基本断点
最基本的断点是在源代码行或函数上设置的断点。注意:如果一个源文件中有超过64000行代码,则不会命中64000行之后的行上的断点。
一行上有多个断点
有时,一行代码包含多个可执行语句。在这种情况下,可以在行上设置多个断点。包含当前选定断点的代码语句周围将出现一个框。此框可用于区分同一行代码上的多个断点。可以在“断点”窗口中选择断点,也可以单击“源”窗口中包含断点的语句。
高级断点
如果您有VisualC++或VisualStudio,任何版本,您可以设置更高级的断点,创建具有高级特性的断点,并以更强大的方式使用断点。
内存地址和内存更改上的断点
可以在内存地址上设置断点,也就是地址断点。在C/C++中,可以设置一个在内存更改时命中的断点,也就是数据断点(仅限本机)。
筛选、命中计数和条件
过滤器、命中计数和条件是可以附加到任何类型断点(包括跟踪点)的高级功能。
- 筛选器导致在指定的计算机、进程和线程上设置断点。在调试运行在多个处理器上的应用程序时,筛选器非常有用。
- 命中计数跟踪断点被命中的次数。默认情况下,断点在每次被命中时都会中断执行。您可以更改此行为,以便只有当命中计数等于或超过指定值或命中计数是给定值的倍数时,断点才会断开。指定的命中计数仅为调试会话保留。
- 条件是一个表达式,计算该表达式以确定断点是否将断开。
断点限制
在调试混合模式、本机和托管代码时,请避免在系统组件上设置断点。在混合模式调试期间在系统组件上设置断点可能会导致公共语言运行库中断,调试器停止响应。除非您单步执行调用,否则调试器不会自动附加到XML Web服务。这意味着在XML Web服务中设置的任何断点都不会被命中,除非您进入调用。如果尝试使用“开始调试”或“继续”来运行断点,而不是使用“单步执行”,则不会命中断点。
设置简单断点
Visual Studio调试器提供了许多设置断点的方法。下面提供了两种设置简单断点的快速方法。
- 在快捷菜单上设置简单断点
在源窗口中,右键单击要设置断点的可执行代码行。在快捷菜单上,单击“断点”,然后单击“插入断点”。 - 在“调试”菜单上设置简单断点
在源窗口中,单击要设置断点的可执行代码行。在“调试”菜单上,单击“切换断点”。
设置地址断点
可以在“反汇编”窗口中的内存地址处设置断点。设置断点后,可以在“断点”窗口中编辑地址断点。先转到汇编窗口,然后进行下面的操作:
在“反汇编”窗口中,单击一行代码,然后单击“调试”菜单上的“切换断点”。
-或者-
右键单击一行代码,然后选择“插入断点”。
设置函数断点
可以在函数的开头或函数中的指定位置设置断点。对于脚本,只能在函数的开头设置断点。
- 插入函数断点
(可选)在源窗口中,单击函数的名称。这会将函数的名称插入到“新建断点”对话框中,以便您不必键入它。
在“调试”菜单上,指向“新建断点”,然后单击“函数断点”。
出现“新建断点”对话框。
如果“函数”文本框不显示要设置断点的函数的名称,请在“函数”框中键入函数名称,并确保“语言”下拉列表显示该函数的正确编程语言。如果函数未重载,则只需要函数名。对于重载函数,可以指定参数以正确设置断点。键入函数名,后跟括在括号中的参数类型名。例如,对于一个名为a的C#方法,它接受一个带字符串参数和int参数,请键入a(int,string)。
在本机C++中,可以使用上下文运算符。(仅限Visual Basic和C)如果希望Visual Studio Intellisense验证输入的函数名,请选中“使用Intellisense验证函数名”复选框。
如果选中该复选框,并且键入的内容与重载签名不匹配,则会出现“选择断点”对话框,您可以选择要放入断点的重载。如果未选中该复选框并键入函数名,则断点将放入所有重载中。如果未选中该复选框,并且键入的签名不匹配,则不会在代码中插入断点。
断点设置在函数的开头。如果要在函数中的其他位置设置断点,请更改“行”和“字符”框中的值。
单击“确定”。 - 从“断点”窗口插入函数断点
后面的操作跟上面一样。
从调用堆栈窗口设置函数调用的断点
此功能不适用于Transact-SQL、Internet Explorer中的脚本或ASP。本主题描述如何使用调用堆栈窗口在对函数的特定调用上设置断点。断点在函数调用中的下一个可执行指令处设置。如果要在函数本身上设置断点,而不是在对函数的特定调用上设置断点。
在“调用堆栈”窗口中,在中断模式下,右键单击函数调用,然后单击快捷菜单(断点子菜单)上的“插入断点”。断点符号出现在函数调用名称旁边的左边距中。查看断点属性时,此断点显示为地址断点,其内存位置与函数中的下一个可执行指令相对应。
设置数据断点(Native Only)
Visual Studio 调试器指南---查看调试器中的数据
Visual Studio 调试器提供了各种用于检查和修改程序状态的工具。 这些工具中的大多数仅在中断模式下有效。
DataTips
数据提示是用于在调试过程中查看程序中的变量和对象的有关信息的最方便工具之一。 在调试器处于中断模式时,可以在当前范围内查看变量的值,方法是将鼠标指针置于源窗口中的变量上。
可视化工具
可视化工具是 Visual Studio 调试器的新组件,通过它可以以有意义的方式查看对象或变量的内容。 例如,可以使用 HTML 可视化工具来查看 HTML 字符串,因为这样可以解释该字符串并在浏览器中显示出来。 您可以通过数据提示、**“监视”窗口、“自动”窗口、“局部变量”窗口或“快速监视”**对话框来访问可视化工具。
变量窗口
可以通过变量窗口来了解变量、寄存器内容和表达式。可以将调试器窗口中使用的数字格式设置为十进制或十六进制。
其他调试器窗口
下面的调试器窗口提供有关程序的重要信息。
查看 |
使用 |
---|---|
寄存器内容 |
如何:使用“寄存器”窗口 |
内存内容 |
如何:使用“内存”窗口 |
|
如何:使用“调用堆栈”窗口 |
由编译器为程序生成的程序集代码 |
如何:使用“反汇编”窗口 |
由您的程序创建线程,即执行的连续流 |
如何:使用“线程”窗口 |
程序使用的模块(DLL 和 EXE) |
如何:使用“模块”窗口 |