1、第5章 VC+调试器,5.1 概述 5.2 VC+调试器界面 5.3 VC+调试器的应用 5.4 高级调试技巧 习题,5.1 概述,5.1.1 调试版本与发行版本VC+中的应用程序能产生两种类型的执行代码:调试版本与发行版本。调试版本是软件开发和检测修改程序的部分,发行版本是最终的结果,将发行给用户。调试版本较发行版本要大,运行起来要慢一些。编译器在目标文件中填满了符号信息,这些符号信息记录了编译器知道的函数名、程序中的变量名和标识的内存地址。,5.1.2 调试功能VC+调试功能包括如下几个方面:(1) 设置断点。(2) 逐步调试代码。(3) 监视变量、注册表和内存。(4) 查看代码和调用堆栈
2、。(5) 修改代码和变量的值。,5.2 VC+调试器界面,5.2.1 Build菜单Build莱单包含的内容如图5-1所示。,图5-1 Build莱单,下面我们介绍图5-1所示的Build菜单中的各项命令。l Compile:用来编译当前的源代码文件,在图5-1中,Compile Example.cpp表示编译Example.cpp文件;l Build:查看当前项目中的所有文件,并对最近修改过的文件进行编译和链接,生成可执行文件。在图5-1中,Build Example.exe表示对当前的文件进行编译和链接,生成可执行文件Example.exe文件;l Rebuild All:忽略以前的编译和
3、链接工作,重新编译和链接整个项目文件;,l Batch Build:成批编译和链接,即一次编译和链接多个项目文件;l Clean:清除当前项目的中间文件和输出文件;l Start Debug:启动程序调试器,用于跟踪程序的调试和执行;l Debuger Remote Connection:对远程调试链接设置进行编辑;l Execute:运行程序;l Set Active Configuration:选择当前项目的配置,例如Win32 Release和Win32 Debug;,l Configuration:编辑项目配置;l Profile:启动剖析器,用于检查程序的运行行为。1Build命令B
4、uild命令用于编译当前项目中所有的C、C+源代码文件或资源文件。 2Start Debug命令Start Debug命令的下级子菜单如图5-2所示。,在Start Debug命令的下级子菜单中,包含了启动调试器运行的各项子命令,子命令及其功能如下:l Go:从程序中的当前语句开始执行,直到遇到断点或遇到程序结束。l Step Into:控制程序单步执行,并在遇到函数调用时进入函数内部。l Run to Cursor:在调试运行程序时,使程序运行到当前光标所在位置时停止,相当于设置了一个临时断点。l Attach to Process:在调试过程中直接进入到正在运行的进程中。,5.2.2 De
5、bug菜单启动调试器后,主菜单栏中的“Build”将被“Debug”所代替,如图5-3所示。,图5-3 Debug菜单,Debug菜单在适当的时候才会出现。比如,打开一个项目文件后,选择Build菜单的 Start Debug项中的Go命令,链接成功后,Debug菜单出现,同时出现Debug工具栏,如图5-4所示。,图5-4 Debug工具栏,使用Debug工具栏按钮可以控制程序的执行。此外,调试器启动后,Edit和View菜单中与调试有关的命令将被激活。通常情况下,Debug工具栏中各个按钮分别对应Debug菜单中相应的菜单项。因此,这里只介绍Debug菜单中的各项命令。Debug菜单各项命
6、令的含义如下:l Go:和Build菜单的Start Debug子菜单中的Go命令作用相同,用于执行程序代码到程序中的断点处;l Restart:重新对程序进行调试,对应的快捷键为Ctrl+Shift+F5;,l Stop Debugging:终止调试过程,返回到编辑状态;l Break:中断正在进行的调试操作;l Apply Code Change:应用对代码的更改;l Step Into:逐步调试程序,遇到调用函数时,进入函数内部逐步执行;l Step Over:也是逐步调试程序,遇到调用函数时,并不进入函数内容执行;l Step Out:调试程序时,从正在执行的某个嵌套结构的内部跳到该结
7、构的外部,常用于知道调用函数中不存在错误的情况;,l Run to Cursor:调试程序时,直接运行到插入点处;l Step Into Specific Function:也是逐步进行程序代码的调试,并且根据指定的信息进入函数的内部;l Exceptions:设置异常处理的一些参数;l Module:显示模块列表;l Show Next Statement:显示程序代码中当前位置的下一条语句;l Quick Watch:快速查看表达式等的值。,5.3 VC+调试器的应用,5.3.1 建立应用程序的调试版本为了创建一个程序的调试执行版本,首先应该保证配置是Win32 Debug。默认情况下,当
8、用户创建一个新项目时,VC+即设置配置为Win32 Debug,如图5-5所示,在Build工具栏中显示当前的配置。,图5-5 Build工具栏显示当前配置,也可以在Build菜单中选择Set Active Configuration命令,以查看当前的配置,看是否有必要将它更改为调试版本。Win32 Debug配置自动改变为程序设置,并在Project Settings对话框中显示出来。通过单击Project菜单中的Settings命令,打开Project Settings(项目设置)对话框,并选择C/C+和Link选项卡,对话框中的设置分别如图5-6和图5-7所示。,图5-6 C/C+选项中
9、的设置,图5-7 Link选项中的设置,其中:(1) 在C/C+选项上的Optimizations下拉列表框中显示Disable(Debug)选项。(2) 在Link选项中,选中Generate Debug Info复选框。有了这些设置,就可以顺利地建立项目了,其结果是一个针对调试器含有符号信息的程序调试版本。,5.3.2 设置断点1通过鼠标和键盘设置断点如果想使用鼠标而不是键盘,可以在此行单击鼠标右键,即可出现一个快捷菜单,如图5-8所示。,图5-8 设置或清除断点的快捷菜单,2通过Breakpoints对话框设置断点虽然比较麻烦,但也可以通过Breakpoints对话框来设置断点。按下Ct
10、rl+B键或在Edit菜单中选择Breakpoints命令,屏幕上将出现如图5-9所示的Breakpoints对话框,该对话框中有三个选项,分别用于设置位置断点、数据断点、条件断点和消息断点,现在我们分别介绍这四种断点类型。,图5-9 Breakpoints对话框,1) 位置断点2) 数据断点在如图5-10所示的Breakpoints对话框中,选择Data选项卡,键入用户想利用调试器进行监视的变量或表达式,例如i5。,图5-10 在Breakpoints对话框中输入数据断点,3) 条件断点在Breakpoints对话框的Location选项卡中设置条件断点,在定义想利用断点标记的源代码后,单击
11、图5-9中的Condition按钮,显示Breakpoint Condition对话框,如图5-11所示。在对话框的顶部控件中,以C/C+条件表达式的形式键入断点条件,例如i3。 4) 消息断点,图5-11 Breakpoint Condition对话框,5.3.3 运行调试器从Build菜单中选择Start Debug命令,将出现一个级联菜单,其下有四个子菜单项,分别为:Go、Step Into、Run to Cursor和Attach to Process,如图5-12所示。各子菜单项的功能前面已介绍过,这里就不再赘述。,图5-12 从Build菜单中启动调试器,5.3.4 调试器窗口调试
12、的程序在某一断点处停止时,调试器更新带有目前程序运行状态消息的窗口。也许调试器窗口中最重要的是源程序窗口,如图5-13所示。,图5-13 从Build菜单中启动调试器,当调试器重新获取控件时,Debug工具栏出现在屏幕上。Debug工具栏中有Debugger Windows的六个按钮以充当触发器,如图5-14所示,显示或隐藏含有目前程序状态消息的窗口。,图5-14 Debug工具栏中的触发调试器窗口按钮,下面是显示在每个窗口中的消息类型:l Watch:通过调试器跟踪的目前变量和表达式的值。在Watch窗口中指定当程序被挂起时,要了解哪些变量的当前值。l Variables:在访问或靠近中断位
13、置处的当前变量值,Variables窗口具有以下三个选项: Auto:显示变量和函数的返回值; Locals:显示当前函数的局部变量;This:在一个C+程序中,标识指针目前所指向的目标。,l Registers:CPU寄存器的当前内容。l Memory:特定地址的内存转储。l Call Stack:没有返回的被调用函数的列表,Call Stack显示通过嵌套函数调用断点位置的执行路径。l Disassembly:在屏幕上,为了补充源程序窗口,其中显示编译代码的汇编语言转换,Disassembly意味着将程序中的机器码转换为相应的汇编指令。,5.3.5 使用调试器1单步调试程序如图5-15所示
14、,Debug工具栏拥有一个四个按钮的调试组,可以通过箭头粗略地了解Step工具。按钮上的图像按次序分别激活Step Into、Step Over、Step Out和Run to Cursor命令。在这之前,我们已经讨论了Run to Cursor命令,其他的三条命令则需要更多的解释。,图5-15 Debug工具栏中的调试按钮,2终止和重新启动调试器如图5-16所示,Restart按钮可以取消执行命令,并从头开始重新运行程序,废弃诸如系统资源或内存之类的分配。 3随机校正4断点编程,图5-16 Debug工具栏中的终止和重新启动按钮,5.4 高级调试技巧,5.4.1 调试过程中的异常处理几乎所有
15、的程序,包括Win32和MFC,都有可能失效,对于多任务环境来说,应用程序共享有限的系统资源更为常见。所谓异常就是指非正常的、意想不到的事情,这些事情可能会改变程序的正常进程,往往需要操作系统进行特殊的处理。,VC+调试器能快速完成截取异常情况,用多线程处理应用程序,调试ActiveX用户和服务器应用程序等工作。当被调试的程序在一台计算机上运行时,调试器还能在另一台计算机上运行。 利用C+异常处理机制,当意想不到的错误发生时,程序可以保留控制权。当函数检测到一个错误时,它通过调用throw关键字来通知异常处理程序,该程序利用catch关键字来获得通知。,5.4.2 调试线程在一个运行的应用程序
16、中,一个线程就是一条运行路径。每个应用程序至少运行一个线程,即主线程或根线程,它也可能生成其他线程。当调试具有多个线程的程序时,用户可以选择要调试哪个线程,并按照其执行流进行调试。只有在调试器开始执行后,才可以选择一个要调试的线程。,5.4.3 调试动态链接库在VC+中调试动态链接库与调试普通的应用程序没有什么区别,不同的只是调试器启动库的调用程序,并没有加载DLL文件本身。 如果关闭 Executable For Debug Session对话框,当用户开始调试动态链接库时,调试器会提示文件名。在库源代码中设置断点后,选择Go命令,或者按下F5键,启动调试器。如果被调用的程序是调试或发行的格式,这两种启动方式将没有多大区别。,习 题,简答题(1) 如何建立应用程序的调试版本?(2) 如何设置位置、数据、条件和信息断点?(3) 怎样开始调试器的运行?,