基础调试知识
- F5 开始使用调试器运行程序
- 在代码编辑器中打开文件,可通过单击代码行左侧的边缘来设置断点。
- 按 F5(“调试”>“开始调试”)或调试工具栏中的“开始调试”按钮,调试器将运行至它遇到的第一个断点。 如果应用尚未运行,则按 F5 会启动调试器并在第一个断点处停止。
- F9 在当前行设置断点
- F10 运行到下一个断点处
- F5 从被调试的已停止程序恢复执行
- F11 步进到函数内(如果当前程序指针指向一个函数)
- F11 是“单步执行”命令,每按一次,应用就执行下一个语句。 使用 F11 启动应用时,调试器会在执行的第一个语句上中断。
- F10 步过函数(如果当前程序指针指向一个函数)
- 按 F10 将使调试器前进,但不会单步执行应用代码中的函数或方法(代码仍将执行)。 按 F10 可跳过你不感兴趣的代码。 这样就可以快速转到更感兴趣的代码。
- Shift+F11 步出执行的函数
- 使用鼠标快速运行到代码中的某个点
- 暂停执行
- 附加到进程(VS调试器可以附加到在 Visual Studio 外运行的进程。)
- Visual Studio 调试器可以附加到在 Visual Studio 外运行的进程。
- 调试并非在 Visual Studio 中创建的应用程序。
- 同时调试多个进程。
- 通过在单个解决方案内启动多个项目来调试多个进程。
- 调试正在远程计算机上运行的进程。
- 调试一个 DLL,该 DLL 运行在不易从 Visual Studio 启动的独立进程上。
- 进程在 Visual Studio 外运行时发生崩溃时,将自动启动调试器。 这就是实时调试。
- 一旦附加到某个程序,就可以使用调试器执行命令、检查程序状态,等等。
- 当然,检查程序的能力可能会受到某些限制,这取决于程序是否用调试信息生成,是否可以访问程序源代码,以及公共语言运行时 JIT 编译器是否在跟踪调试信息。
- 鼠标悬停时快速查看源代码中的元素
- 调试窗口:局部变量、监视、即时窗口、模块、调用堆栈、异常设置
- 监视窗口
- 配置应用程序,使应用程序处于调试状态。
- 点击“调试”—-“窗口”—-“监视”—-“监视1”,打开监视窗口。
- 在监视窗口中“名称”栏中输入变量名称或html元素id,可查看变量的当前值和数据类型或html元素的属性、方法、事件等。
- 亦可选中变量,将其拖到“名称”栏,即可查看变量的当前值和数据类型
- 即时窗口
- 配置应用程序,使应用程序处于调试状态。
- 点击“调试”—-“窗口”—-“即时”,打开即时窗口。
- 在即时窗口中输入变量名或html元素对应的属性,即可查看变量的当前值或html元素的属性、方法的值。
- 输出窗口
- 点击“调试”—-“窗口”—-“输出”,打开输出窗口。
- 输出窗口能输出程序的的编译信息等,用Debug类和Trace类输出的内容就是现实到输出窗口上。
- 配置输出窗口字体颜色,“工具”—-“选项”—-“环境”—-“字体和颜色“,选中输出窗口(可以为其他的窗口,如即时窗口等设置内容的字体颜色)。
- 配置在输出窗口上显示哪些信息,“工具”—-“选项”—-“调试”—-“输出窗口”。
- 可以将输出窗口上的Debug类和Trace类输出的内容重定向到即时窗口,这样可以只关注输出的调试信息,“工具”—-“选项”—-“调试”,选择将所有输出窗口文本重定向到即时窗口。
- 调用堆栈
- 可以找到当前函数的调用函数,以及依次往前的每一级调用函数
- 调用堆栈窗口会按照函数的调用顺序来显示,顶部为栈顶,栈底的函数最先被调用,函数调用称为栈帧。
- 调用堆栈窗口中的函数信息的内容主体是个函数栈,最上面的函数,就是第一级函数,是最后被调用的函数,也是在打上断点调试的情况下,当前进程运行到的位置,
- 第一级函数下面的第二级函数,就是调用了第一级函数的函数,
- 第二级函数下面的第三级函数就是调用了第二级函数的函数,
- 通过调用堆栈窗口可以很容易的理清当前运行到的位置函数的调用函数,也就是上一级函数是谁,通过在调用堆栈中双击某个函数就可以跳转过去。
- 监视窗口
设置符号信息
场景:
在当前工程引入了外部动态库的情况下,程序员准备好了该动态库的源码,准备将源码附加到运行中的进程进行调试,排查有可能出现在动态库中的bug。
pdb符号文件:
pdb文件就是文件后缀为.pdb的文件,pdb文件和动态库一起生成,名称和其对应的动态库相同,动态库常有更新时,对应的调试符号pdb也必须时刻与对应的源代码同步。
用法:
将准备好的源代码附加给正确的进程号,调用堆栈窗口可以显示该进程调用到的动态库和函数,右键窗口-》符号设置,将保留pdb文件的路径复制到符号路径下,点击确定,编译器会自动加载符号,路径下的pdb会全部加载到当前进程中与之对应的被调用的动态库,也有部分动态库找不到pdb符号文件,但只要需要被调试的模块加载好了符号,就可以在该模块中打上断点,然后触发事件进行调试了。
————————————————————————————
版权声明:本文为CSDN博主「优秀的邓宗磊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ganfanren00001/article/details/121578345
————————————————————————————
异常处理
异常是在程序运行时发生的不正常情况。 异常通常表示有需要调试的问题。 发生异常时,调试器将向“输出”窗口中写入一条异常消息,但在““选项”对话框 ->“调试”->“常规””对话框中禁用了该选项的情况除外。
发生异常时,调试器不一定会中断执行。
- 如果发生了非 ASP.NET 异常并且没有进行处理,调试器总是会中断执行。
- 您可以让调试器在引发异常时立即中断执行(在调用任何处理程序之前)。
- 如果使用 如何:单步执行“仅我的代码” 进行调试,您还有第三个选项。 您可以让调试器在遇到任何未由用户代码(“我的代码”)中的处理程序处理的异常时中断执行。 有关更多信息,请参见如何:在遇到用户未经处理的异常时中断。
- ASP.NET 有一个顶级异常处理程序,该处理程序在对异常进行处理时向浏览器用户显示错误页面。 该顶级异常处理程序会阻止未经处理的异常中断到调试器中,除非打开了“仅我的代码”。 请确保对 ASP.NET 调试启用“仅我的代码”。请记住,如果发生了异常但根本没有进行处理,调试器总是会中断执行。 用户未处理的设置不会更改这一行为。
Visual Studio 调试器识别下列类别的异常:
- C++ 异常
- 公共语言运行时异常
- 托管调试助手
- 本机运行时检查
- Win32 异常
大多数异常都有相应的处理程序,用于在异常发生时做出响应。 这样程序便有可能从异常状况中恢复过来。 本机运行时检查没有处理程序。在 Visual Basic 应用程序中,调试器将所有错误都表示为异常,即使使用 On Error 样式的错误处理程序。对于 Visual Basic 和 C#,调试器现在具备了一项新增的异常助手功能,此功能可在发生异常时提供更多信息。
在引发异常时中断
调试器可以在发生异常时立即中断应用程序的执行,使您有机会在调用处理程序之前对异常进行调试。
如果您在启用 如何:单步执行“仅我的代码” 的情况下进行调试,行为会略有不同。 启用“仅我的代码”时,调试器将忽略在“我的代码”以外引发并且不通过“我的代码”的最可能的公共语言运行时 (CLR) 异常。 但是,如果该异常完全未进行处理,调试器将始终中断。
如果将调试器设置为在引发 CLR 异常时中断且调试器在发生 CLR 异常时中断,则某些情况下调试器突出显示的行可能会稍有偏差。 例如,如果从托管代码的 if 语句内部引发异常,就可能发生这种情况。 调试器突出显示要执行的下一个 CLR 指令所在的行,即 throw 之后的行,而不是 throw 语句所在的行。
默认情况下,“异常”对话框列出每一类别中最常见的异常。 您可以添加自己的异常和删除所添加的异常。 Visual Studio 将添加的异常的列表与解决方案数据保存在一起,这样在下一次打开和运行项目时这些异常将可用。
设置在引发异常时中断执行
- 在“调试->窗口”菜单中,单击“异常”。
- 在“异常”对话框中,为整个类别的异常(如“公共语言运行时异常”)选择“引发”。或展开一个类别的异常(如“公共语言运行时异常”)的节点,并为该类别中的特定异常选择“引发”。
在“调试”菜单中添加“异常”命令
- 在“工具”菜单上,单击“自定义”。出现“自定义”对话框。
- 单击“命令”选项卡,在“菜单栏”列表中,单击“调试”。
- 单击“添加命令”。
- 在“添加命令”对话框的“类别”中,单击“调试”。
- 在“命令”中,单击“异常设置”,然后单击“确定”。
- (可选)可以单击“下移”以调整“异常”命令在“调试”菜单中的位置。
- 单击“关闭”。
在遇到用户未经处理的异常时中断
如果使用 如何:单步执行“仅我的代码” 调试,可以让调试器在发生任何没有由用户代码(“我的代码”)中的处理程序进行处理的异常时中断。 下面的过程显示了如何使用“异常”对话框来确定要在发生哪些用户未经处理的异常时中断。
默认情况下,“异常”对话框列出每一类别中最常见的异常。 您可以添加自己的异常和删除所添加的异常。 Visual Studio 将添加的异常的列表与解决方案数据保存在一起,这样在下一次打开和运行项目时这些异常将可用。
- 在“调试”菜单中,单击“异常设置”。
- 在“异常”对话框中,为整个类别的异常(如“公共语言运行时异常”)选择“用户未处理的”。- 或 -展开某种异常类别(如“公共语言运行时异常”)的节点,并为该类别中的特定异常选择“用户未处理的”。
- 单击“确定”。
在出现异常之后继续执行
由于出现异常而执行调试器中断时,会显示一个对话框。 对于 Visual Basic 或 C#,在默认情况下,您将看到异常助手对话框。 对于 C++,您将看到早期的 “异常” 对话框。 如果您使用的是 Visual Basic 或 C#,但在“选项”对话框中禁用了“异常助手”,您将看到“异常”对话框。
出现“异常助手”或“异常”对话框时,可尝试对导致异常的问题进行修复。
托管代码
在托管代码中,您可以在出现了未经处理的异常后在同一线程内继续执行。 “异常助手”将调用堆栈回退到引发异常的点。
本机代码
在本机 C/C++ 中,您有两个选项:
- 您可以单击“中断”并尝试修复问题。 在中断模式下,右击“调用堆栈”窗口中的帧并选择快捷菜单中的“展开到此帧”来展开调用堆栈。 如未能修复问题,则继续调试时,“异常”对话框将再次显示。 否则,“异常”对话框将不会出现。
- 您可以单击继续执行,不尝试修复问题。 “异常”对话框随即重新出现。
混合模式
如在调试本机和托管混合代码时遇到未处理的异常,操作系统约束将会阻止调用堆栈展开。 如果尝试使用快捷菜单来展开调用堆栈,则会出现一个错误消息,告诉您在混合代码调试期间,调试器无法在异常未得到处理的情况下展开调用堆栈。
在发生异常后检查系统代码
发生异常时,您可能需要检查系统调用内部的代码,以确定该异常的起因。 如果您没有为系统代码加载符号,或者启用了“仅我的代码”,则下面的步骤说明了如何执行此操作。
在发生异常后检查系统代码
- 在“调用堆栈”窗口中右击,然后单击“显示外部代码”。如果未启用“仅我的代码”,则快捷菜单中不提供此选项,默认情况下显示系统代码。
- 右击此时显示在“调用堆栈”窗口中的外部代码帧。
- 指向“加载符号”,然后单击“Microsoft 符号服务器”。
- 如果启用了“仅我的代码”,则将显示一个对话框。 它指出“仅我的代码”现在已禁用。 要单步执行系统调用,必须这样做。
- 将出现“正在下载公共符号”对话框。 下载完毕后会自动关闭该对话框。
- 现在即可在“调用堆栈”窗口和其他窗口中检查系统代码。 例如,您可以双击调用堆栈帧在源窗口或“反汇编”窗口中查看代码。
使用本机运行时检查
在 Visual C++ 中,可以使用本机 runtime_checks 捕捉常见的运行时错误,例如:
- 堆栈指针损坏。
- 本地数组溢出。
- 堆栈损坏。
- 未初始化的局部变量上的依赖项。
- 较短变量赋值的数据丢失。
如果使用带有优化 (/O) 版本的 /RTC,将导致编译器错误。 如果在优化版本中使用 runtime_checks 杂注,则该杂注无效。
调试启用了运行时检查的程序时,如果出现运行时错误,该程序的默认操作是停止并切换到调试器。 可以更改任何运行时检查的此默认行为。 有关更多信息,请参见 异常处理(调试)。
在调试版本中启用本机运行时检查
- 使用 /RTC 选项,并与 C 运行库(如 /MDd)调试版链接。
使用无 C 运行库的运行时检查
如果链接程序而不链接 C 运行库(使用 /NODEFAULTLIB)并希望使用运行时检查,则必须链接 RunTmChk.lib。
_RTC_Initialize 为运行时检查初始化程序。 如果未链接 C 运行库,必须在调用 _RTC_Initialize 之前检查是否用运行时错误检查编译了程序:
#ifdef __MSVC_RUNTIME_CHECKS
_RTC_Initialize();
#endif
如果不链接 C 运行库,还必须定义一个称为 _CRT_RTC_INITW 的函数。 _CRT_RTC_INITW 将用户定义的函数安装为默认的错误报告函数,如下所示:
// C version:
_RTC_error_fnW __cdecl _CRT_RTC_INITW(
void *res0, void res1, int res2, int res3, int res4)
{
// set the error handler.
return &MyErrorFunc;
}
// C++ version:
extern "C" _RTC_error_fnW __cdecl _CRT_RTC_INITW(
void *res0, void res1, int res2, int res3, int res4)
{
// set the error handler:
return &MyErrorFunc;
}
安装了默认错误报告函数后,可以使用_RTC_SetErrorFuncW 安装附加错误报告函数。
————————————————————————————
版权声明:本文为博客园博主「活着的虫子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://www.cnblogs.com/yilang/p/12462458.html
————————————————————————————
发表回复