第07天 使用VS 2019调试程序
视频讲解
今天要学习的案例对应的源代码目录:src/chapter02/ks02_05。本案例不依赖第三方类库。程序运行效果如图2-23所示。
今天的目标是掌握如下内容。
- 使用VS 2019调试程序时,将待调试项目设为启动项目。
- 为程序设置命令参数。
- 调试时设置、取消断点,启用、禁用断点,查看当前断点列表。
- 开始调试、停止调试、开始执行(不调试)。
- 逐语句调试、逐过程调试。
- 调试时查看变量的值。
- 添加对变量的监视。
- 查看堆栈。
- 使用书签定位代码。
- 调试已经处于运行状态的程序。
对于开发人员来说,使用IDE环境调试程序是日常工作之一。本节以ks02_05的代码为例,介绍使用VS 2019调试程序的基本方法。
图2-23 使用VS 2019调试项目时的运行效果
1.使用VS 2019调试程序时,将待调试项目设为启动项目
VS 2019可以加载解决方案文件(后缀为.sln),一个解决方案可以包含多个项目。因此,首先应确定启动哪个项目进行调试,方法是在VS 2019的【解决方案管理器】窗口中右击待调试的项目,在弹出的菜单中选择【设为启动项目】。
注意:将DLL项目设置为启动项目时,如果未设置项目的启动命令(调用该DLL的EXE程序),那么在调试时会提示无法启动该DLL,如图2-24所示。为项目设置启动命令的方法是在VS 2019的【解决方案管理器】窗口中右击待调试的项目,在弹出的菜单中选择【属性】,在弹出的属性页中选择【配置属性】|【调试】|【命令】,如图2-25所示。
图2-24 无法启动DLL
2.为程序设置命令参数
设置好启动项目后,接下来需要确定程序的命令参数。如果需要为程序设置命令参数,可以在【解决方案管理器】窗口中右击待调试的项目,在弹出的菜单中选择【属性】,在弹出的属性页中选择【配置属性】|【调试】|【命令参数】,如图2-26所示。本次调试设置的命令参数为:-term -f c:/config/custom.xml。这相当于用如下方式启动程序:ks02_05_d-term -f c:/config/custom.xml。
图2-25 为DLL项目设置启动命令
图2-26 设置调试用的命令参数
3.调试时设置、取消断点,启用、禁用断点,查看当前断点列表
如果程序一直处于高速运行状态,开发人员仅能通过查看日志或者是程序界面中的数据来观察程序的运行状态。但是这种方法只能查看日志或界面中显示的内容,如果希望查看程序中某个变量的当前值,通过日志或界面进行查看的方法就行不通了。此时,可以为程序设置断点和中断条件,当程序产生中断后,VS 2019就会把程序的状态保持住,这样再通过VS 2019提供的手段查看变量的值即可。如果没有其他条件,仅仅希望程序中断,可以直接在期望中断的代码行设置断点,方法是单击代码行,在该行代码左侧的灰色框位置单击,即可设置或取消断点(单击可设置断点,再次单击则取消断点)。如果希望当满足某个条件时才在指定代码处产生中断,可以在添加断点后设置中断条件,方法是将鼠标指针移动到断点处,就会显示【设置】按钮和【禁用断点】按钮,如图2-27所示。单击【设置】后弹出【断点设置】界面,如图2-28所示。在【断点设置】界面中单击【条件】复选框,在图2-29所示位置编写中断条件即可。可以为同一处断点设置多个条件。当程序执行到该行代码处并且满足这些条件时,将触发中断,此时就可以进一步查看堆栈或变量的值以便进一步分析。
图2-27 设置、取消断点和设置、禁用断点
图2-28 断点设置
图2-29 为断点添加条件
有时候,需要暂时禁用某些断点,通过单击断点处的【禁用断点】按钮可以实现禁用/启用断点的功能,如图2-27所示。如果想禁用或启用所有断点,可以通过【调试】|【禁用所有断点】和【调试】|【启用所有断点】来实现。如果想查看当前所有的断点,可以通过选择【调试】|【窗口】|【断点】调出【断点】窗口,如图2-30所示。
图2-30 【断点】窗口
4.开始调试、停止调试、开始执行(不调试)
做好前面的准备工作后,就可以开始调试了。选择【调试】|【开始调试】可以启动调试,选择工具栏中的【本地Windows调试器】也可以启动调试,如图2-31所示。启动调试的默认快捷键为F5。当发生中断后继续调试程序时方法同启动调试一样。另外,还可以选择不调试直接执行目标程序,方法是选择【调试】|【开始执行(不调试)】。
图2-31 使用工具栏按钮启动调试器
5.逐语句调试、逐过程调试
启动调试后,调试器会在满足中断条件时停在断点处。此时,可以查看堆栈或变量的值,然后选择继续调试。继续调试时,可以继续使用逐语句调试或逐过程调试。逐语句调试指的是把代码一句一句进行调试,即每调试一步只执行一句代码,默认快捷键是F11;逐过程指的是以函数为单位进行调试,即每调试一步执行一个函数,默认快捷键是F10。实际工作中可根据实际需要选用不同的调试方法。当然,也可以继续使用F5,直到程序在下个断点处中断。
6.调试时查看变量的值
启动调试的一个重要目的是检查程序的运行状态,通过查看变量的值可以检查程序的运行状态。只有在调试会话期间,才可以查看变量的当前值。查看变量的当前值有以下几种方法。
(1)直接把鼠标悬浮在变量上方,VS 2019会显示该变量的值,如图2-32所示。
(2)在【自动窗口】中,也可以查看当前栈内可见或改变的数据,如图2-33所示。可以在变量上右击,选择以十进制或十六进制方式显示变量的值,如图2-34所示。可以通过【调试】|【窗口】|【自动窗口】调出【自动窗口】。【自动窗口】中还可以查看当前刚调用过的函数的返回值。
图2-32 鼠标悬浮在变量上方时显示变量的当前值
图2-33 在【自动窗口】中查看变量的当前值
图2-34 以十六进制显示变量的值
(3)在【局部变量】窗口中,可以查看当前函数内的变量,如图2-35所示。可以通过【调试】|【窗口】|【局部变量】调出【局部变量】窗口。
图2-35 【局部变量】窗口
7.添加对变量的监视
如果想查看的变量不在当前中断的函数内,可以事先将变量添加到监视窗口,这样就可以查看不在当前函数内的变量的值。可以通过【调试】|【窗口】|【监视】菜单中的4个监视窗口菜单分别调出【监视1】【监视2】【监视3】【监视4】4个监视窗口。通过将变量直接拖放到监视窗口可以实现对变量的监视。只有在产生中断的情况下,才能够查看被监视的变量的当前值。
8.查看堆栈
有些情况下,需要查看当前代码的堆栈调用情况。所谓堆栈,就是函数之间的调用关系,也就是当前的函数是被哪个函数调用的。如图2-36所示,当前中断位于CommandProc()的第101行代码处,从【调用堆栈】窗口可以看出函数的调用关系:当前处于CommandProc()行101,它是被下一行的main()行84调用的,也就是在main()函数的第84行代码处调用了CommandProc()。这里的84行指的是main()所在源代码文件的84行,并非main()函数开始之后的第84行。
图2-36 调试中的堆栈
9.使用书签定位代码
在分析问题时,开发人员可能需要在代码中做些记号,以便再回头查看这些代码,这可以通过为代码行增加书签来实现。通过【编辑】|【书签】|【切换书签】可以实现该功能。如图2-37所示。添加书签的快捷键默认为Ctrl+F2,即添加、删除书签都可以通过该快捷键实现。在各个书签之间切换的快捷键默认为F2。
图2-37 代码中的书签
10.调试已经处于运行状态的程序
如果程序一直处于运行状态而非调试状态,这时候如何用VS 2019进行调试呢?可以使用VS 2019的【附加到进程】功能。首先启动VS 2019并加载待调试程序对应的项目(即项目的vcxproj文件),然后选择【调试】|【附加到进程】,会弹出【附加到进程】界面,在【可用进程】列表中找到待调试的进程,单击【附加】按钮即可,如图2-38所示。
图2-38 附加到进程
注意:不能使用VS 2019调试Release版本的程序,因为即使启动调试也无法查看变量或堆栈。