Delphi应用程序的调试(二)使用断点
使用断点(Using Breakpoints)
当用户从Delphi IDE 运行程序时,程序全速运行,只会在设置了断点的地方停住。
New Term
断点(breakpoint)是一种标记,用以通知编译器,当程序运行到断点所在位置时暂停程序的执行。
设置和清除断点(Setting and Clearing Breakpoints)
断点的设置可通过点击Code Editor的沟槽来进行;要在代码的某一行暂停程序执行,就在沟槽中与该行相对应的位置上点击鼠标,该行就被设置上一个断点;此时,沟槽中出现一个断点图标(一个红色圆圈),并且断点所在行以红色加亮显示,如下图:
点击沟槽中的断点图标,与之对应的断点就会被删除。也可以按【F5】键或从Code Editor的快捷菜单中选择【Toggle Breakpoint】菜单项来触发或取消断点。
Note
只允许在能生成实际代码的行上设置断点。在空白行、注释或声明行上设置的断点时无效断点,当用户在这一类的行上设置断点,调试器会提出警告。试图在下列行上设置断点,都会产生一个无效断点警告:
可在函数或过程的end语句行上设置断点。
如果在无效行上设置断点,Code Editor会以绿色显示断点,如上图所示。
在调试器下运行的程序,在不碰到断点时,与通常的程序运行完全一样;当碰到断点时,IDE会被提到最顶层,并且源代码中的断点所在行被加亮显示。如果使用的是缺省颜色格式,则程序停止处的行以红色加亮显示,如下图,红色断点旁有一个绿色小箭头:
New Term
执行点(execution point)是指源代码中下一步要执行的代码行。
当用户一步一步调试程序时,执行点以蓝色加亮显示,并且在Code Editor沟槽中显示一个绿色箭头符号。提醒:以蓝色加亮显示的行还未被执行;当恢复程序执行时才执行它。如下图:
Note
当执行点所在行以蓝色加亮显示,除非该行包含一个断点(此时,该行以红色加亮显示)。沟槽中的绿色箭头是当前执行点的最精确指示,因为它不受加亮显示颜色的影响。
当程序在断点处暂停执行时,用户可查看变量、查看调用栈、浏览符号或在代码中步进。检查完变量和对象后,可点击Run按钮恢复程序的执行,这时应用程序就会再次正常运行,直至碰到下一个断点。
Note
当程序在断点处暂停执行后,用户一般都要检测代码编写错误。如果用户在调试会话中间修改了源代码,然后按Run按钮恢复程序执行,IDE就会显示一个消息框提示用户是否要重建源代码;如果用户选Yes,当前过程就会被终止,源代码被重新编译,并重新启动该程序。
这样操作就有一个问题,程序无法正常关闭,当前正使用的资源未被释放。这样极可能导致内存泄露(memory leaks)。建议大家正常终止程序,然后再重新编译应用程序。
断点列表窗口(The Breakpoint List Window)
Delphi IDE记载用户设置的断点,可通过Breakpoint List(断点列表)窗口查看这些断点。从主菜单上选择【View | Debug Windows | Breakpoint】菜单项来查看断点列表,如下图:
Note
Pass栏不是显示某个断点被碰上的次数,它只是显示用户为断点设置的通过条件。
1、快捷菜单(Breakpoint List Context Menus)
- Enabled——允许使用或禁止使用某个断点。如果一个断点被禁止使用,它在Breakpoint List窗口中的符号就会变灰;它在源窗口中的断点符号也会变灰;并且该断点所在行以绿色加亮显示,表示该断点被禁用。如下图:
- Delete——删除断点。
- View Source——滚动Code Editor中的源文件来显示包含断点的源代码行。
- Edit Source—— 将编辑光标放置到源代码中包含断点的行上。并将输入焦点切换到Code Editor上。
- Properties—— 显示“Source Breakpoint Properties”断点属性对话框。
- Breakpoints—— 显示断点有关的子菜单,如下图:
- Dockable—— 确定“Breakpoint List”窗口是否可泊位。
Note
快捷菜单中的【Add】菜单项作用不大,因为,在Code Editor中设置断点要比通过Breakpoint List窗口中的Add命令来添加断点容易的多。
2、断点的启用和禁用(Enabling and Disabling Breakpoints)
用户在任何时候都可以禁止和启用断点。如果用户想要正常运行程序,就可将程序中的断点暂时禁用;以后需要时可启用该断点而不必重新创建它。调试器忽略被禁用的断点。
要启用或禁用一个断点。在“Breakpoint List”窗口中用鼠标右键点击该断点,并从快捷菜单中选择【Enabled】项。
3、修改断点(Modifying Breakpoints)
要修改断点,可从“Breakpoint List”窗口中选择【Properties】菜单项,此时会显示“Source Breakpoint Properties”对话框,如下图:
修改断点的主要原因是增加断点条件,在之后的讲解中将要重点介绍。
要删除一个断点,可在“Breakpoint List”中选择该断点,并按键盘上的【Delete】键盘。要删除所有断点,可单击鼠标右键,然后选择【Delete All】。
下面将要讲解断点的两种类型:简单断点和条件断点。
简单断点(Simple Breakpoints)
简单断点是指这样一种断点,程序一执行到断点处就会被挂起。按缺省方式设置的断点就是简单断点。简单断点不需要多作解释。一碰到简单断点,程序执行就会暂停,此时调试器等待用户的输入。大多数时候都是使用简单断点;当用户需要更多地控制调试过程时,才使用条件断点。
条件断点(Conditional Breakpoints)
若碰到的断点是条件断点,则仅当预定义的条件满足时,才会暂停程序执行。
要创建一个条件断点,可先在Code Editor中设置该断点;然后从主菜单选择【View | Debug Windows | Breakpoint】菜单项调出“Breakpoint List”窗口,用鼠标右键点击要设置的断点并选择【Properties】菜单项,显示出“Source Breakpoint Properties”对话框,在此对话框中设置断点的条件。
条件断点有两种类型:
- 第一种类型是条件表达式断点。
在“Source breakpoint Properties”对话框中的“Condition”字段中输入条件表达式。如下图:
当程序运行时,碰到条件表达式断点就会先求条件表达式的值,若条件表达式的值为True,则暂停程序执行;若条件表达式的值为False时,则该断点被忽略。
例如:设置的条件表达式为:X > 20;当程序运行到该断点时,若X大于20则暂停程序的执行;若X不大于20,则程序继续往下执行。 - 第二种类型是通过计数(pass count)断点。
对于一个通过计数断点,只要当碰上该断点的次数达到指定次数时,程序才会在该断点处暂停执行。要指定一个通过计数断点,可在“Source Breakpoint Properties”对话框中编辑该断点并为Pass Count字段指定一个值。若将一个断点的通过计数设置成3,则程序会在第三次碰到该断点时暂停程序执行。Note
通过计数是从1开始,不是从0开始。就像前面所指出的,通过计数为3,意味着当程序第三次碰上某个断点时,该断点才有效。
当程序需要在程序执行通过某个断点若干次后再暂停程序执行来检查变量、步进调试代码或执行其他调试任务时,可使用通过计数断点。Note
条件断点会放慢程序的执行速度,因为每当碰上条件断点时,都要对条件求值。在调试期间,如果程序运行缓慢,可检查一下断点列表,看是否存在不必要的条件断点。
Note
用户可灵活运用条件断点来减慢程序执行速度。如果用户希望某段程序低速运行以便查看,可在该代码段中设置一个或多个条件断点。将断点的条件设置成永远不能成立的条件,则程序执行会放慢速度,但不会停住。
运行至光标处命令(The Run to Cursor Command)
还有一个调试命令值得一提,就是“Run to Cursor”命令,可从主菜单【Run | Run to Cursor】选择此命令。当用“Run to Cursor”命令运行程序时,程序会在包含编辑光标的源代码行上停止运行,就好像该代码行上设置有断点一样。如下图:
“Run to Cursor”可用作临时断点。当用户要马上检查某行源代码时,不必在该行上设置断点;只需将光标移到这一行上,然后选“Run to Cursor”(或按F4键),调试器会在程序运行至该行时暂停程序执行。就好像该行上设置了断点一样。使用“Run to Cursor”的好处是:当完成一段代码的调试后,不必清除断点。