第十二章 异常处理与程序调试(三)
12.4.3 断点的使用
12.4.3.1 设置断点
设置断点首先在Code Editor中选定你想设置断点的代码行,而后进行如下的任一种操作:
单击选定代码行左边的空白
按F5
选择Code Editor加速菜单的Toggle BreakPoint项
选择Run|Add Breadpoint打开断点编辑对话框(Edit BreakPoint Dialog Box),而后选择New去确认一个新的断点设置或选择Modify去对一个存在的断点进行修改
从BreakPoint List加速菜单中选择Add BreakPoint项
断点必须位于可执行代码行上,凡设置在注释、空白行、变量说明上的都是无效的。另外,断点既可以在设计状态下设置也可以在运行调试状态下设置。
12.4.3.2 断点的操作
断点列表窗口(BreakPoint List Window)列出了所有断点所在的源文件名、行号、条件以及已通过的次数。如果一个断点非法或失去功能,则在列表窗口中变灰。
断点列表窗口可以通过选择View|BreakPoint菜单打开。
断点列表窗口是断点操作的基础。
1.显示和编辑断点处的代码
利用断点列表窗口可以快速找到断点在源代码中的位置。
首先选定断点而后从加速菜单中选择View Source或Edit Source。此时Code Editor更新,显示该断点位置处的代码。如果选择的是View Source,则断点列表窗口仍保持活动;如果选择的是Edit Source,则Code Editor获得输入焦点,可以在断点位置修改源代码。
2.断点功能的丧失和恢复
使断点失去功能可以使断点从当前程序运行中隐藏起来。假如你定义了一个断点当前并不需要,但可能在以后使用,则这一功能是很有用的。
断点列表窗口加速菜单的Disable BreakPoint和Disable All BreakPoints项可以使当前选中断点或所有断点失去功能。
加速菜单中的Enable BreakPoint和Enable All BreakPoint 可以使相应断点恢复功能。
3.断点的删除
断点删除可以从Code Editor或断点列表窗口中进行。
从Code Editor:
把光标停到包含断点的行并按F5(或选择加速菜单的Toggle BreakPoint)
单击包含断点行左边的终止符
从断点列表窗口:
选中欲删除的断点并选择加速菜单的Delete BreakPoint项
删除当前所有断点,则选择加速菜单的Delete All BreakPoints项
12.4.3.3 修改断点属性
断点列表窗口双击选定断点或从加速菜单中选择Edit BreakPoint项,可以打开断点编辑对话框,用于显示和修改断点的属性。
利用断点编辑对话框可以改变断点的位置,设置断点条件。
断点条件包括两种:布尔表示式和通过次数。
Condition编辑框用于设置布尔表达式条件。如果表达式值为真(或非零)则程序运行在断点处中止;否则调试器将忽略该断点。
Pass Count编辑框用于设置通过次数条件,即只有当程序运行在该断点处通过设定次数时程序运行才在该断点处中止。这往往用于对循环体内语句的调试。
有一点应引起注意的是:当Condition和Pass Count同时设置时,Pass Count是指满足条件的通过次数。
对如下一段程序:
var
i,Re,s: Integer ;
begin
s := 1;
Re := 0;
for i:=1 to 100 do
Re:=Re+s*i ;
end;
在 Re := Re + s*i; 一行设置一断点。
若条件设置为:
Condition :i = 3
Pass Count: 4
则当程序中止时检测i 的值为7。
12.4.3.4 断点和程序执行点颜色的设置
选择Option|Environment进入环境设置对话框而后选择Editor Colors页标签。此时即可对有关项按自己的希望设置背景和前景色。
12.4.4 监视数据的值
内置调试器提供了如下的工具用于监视程序中数据的值:
监视列表窗口
计算/修改对话框
调栈窗口
12.4.4.1 监视表达式
监视列表窗口(Watch List Window)显示程序运行中当前监视表达式的值。
选择View|Watches可以打开监视列表窗口。
从Code Editor中添加一个监视表达式最方便的方法是:
1.选中要监视的表达式;
2.从Code Editor加速菜单中选择Add Watch把表达式添加到监视列表窗口。
也可以利用下面的方法产生一个监视表达式:
1.用下列方法之一打开监视属性对话框(Watch Properties Dialog Box):
●主菜单中选择Run|Add Watch
●在光标处从Code Editor加速菜单中选择Add Watch
●按Ctrl-F5
●双击监视列表窗口中的一个监视表达式
●从监视列表窗口选定一个表达式而后从加速菜单中选择Edit
2.在监视属性对话框的Expression下拉列表框中输入或选择一个被监视的表达式;
3.设定表达式的显示格式和使能状态。
与断点类似,利用加速菜单也可以使监视表达式功能丧失、恢复或删除监视表达式。
12.4.4.2 计算/修改表达式
选择Run|Evaluate /Modify可打开计算/修改对话框。当单击Evaluate按钮时,Expression编辑框中表达式的值显示在Result域中。
Expression中可以输入或选择任何合法的表达式(包括对象的属性),但不包括;
1.包含有当前执行点不能引用的局部或静态变量的表达式;
2.函数或过程调用。
Expression中的表达式可以带特定的格式字符用于规定其显示格式。 格式字符及其功能如下表。
表12.8格式字符及其功能
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
格式字符 功 能
─────────────────────────────────
$,H,X 以十六进制格式显示标量
D 以十进制格式显示标量
C 把ASCII码在0..31的特殊字等显示为ASCII码图形
Fn 用n个有效数字显示浮点数
M 以十六进制方式显示一变量的内存转储值
P 以段和偏移量格式显示指针。两部分皆为四位十六进制值
R 显示记录、对象的域名和值(例如 X:5,Y:2)
S 用ASCII码显示字符串(包括特殊字符)。用于修改内存转储值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
修改表达式的值常用于验证错误解决方案的正确性。在Expression编辑框中输入或选定欲修改的表达式,单击Evaluate按钮观察表达式的当前值。而后在New Value编辑框中输入或选中一个新值,并单击Modify按钮确认并更新数据项。这种修改只影响特定的程序运行。
修改表达式的值(特别是指针变量和数组下标)可能会引起无法预计的后果。因而使用中要特别小心。
12.4.4.3 显示函数调用
选择View|Call Stack可以显示调栈窗口(Call Stack Window)。调栈窗口的顶端列出了应用程序最近的函数调用。
利用调栈窗口可以退出当前跟踪的函数,可以利用加速菜单项显示或编辑位于特定函数调用处的源代码
12.5 其它调试工具
Delphi的内置调试器虽然功能很强大,但并不能胜任所有的任务。同时由于内置调试器在执行中引起程序环境的细微变化,所以可能影响错误的发生方式。为此我们需要使用其它调试工具来完成我们的任务。这些调试工具包括Turbo Debugger、WinSight、WinSpector和Browser。Browser将在下一节中专门进行介绍。
12.5.1 Turbo Debugger
Turbo Debugger是Borland公司推出的第三代语言调试器,它虽然还没有推出完全支持Delphi的新版本,但也基本能胜任一般Delphi程序的调试。
Turbo Debugger在字符模式下执行,但它是一个真正的Windows程序,它仅使用基于字符的界面。由于Turbo Debugger是一个准备控制其它程序的特殊程序,因此不可以使用通常Windows任务切换功能如Alt+Tab。
Turbo Debugger的操作大部分与内置调试器相同或类似。利用File|Open菜单装入要调试的文件就可以开始一个调试过程。
利用Turbo Debugger必须把调试符号信息储存在可执行文件中。具体操作见(12. 4.1.1)中介绍。
Turbo Debugger与内置调试器相比,有许多新的功能。
首先它提供了许多在低级硬件信息方面的控制。可以完全访问CPU的寄存器、标志及系统内存。用户可以跟踪远指针到内存位置并直接检查它们的内容。Turbo Debugger可以跟踪进到代码中,即使得不到源代码也可以。
Turbo Debugger支持许多Windows的特殊功能。它可以跟踪Windows消息,让用户查看程序的局部堆和全局堆,并可以浏览包括DLLs在内的组成程序的所有代码单元列表。
另外Turbo Debugger支持远程执行能力。可以通过串口链接或通过支持NetBIOS的网络配置Turbo Debugger控制另外一台机器。在这种模式下,一台机器显示调试器屏幕,另一台机器显示被跟踪的程序。这允许在一个屏上单步执行程序并在另一屏上监视结果。
12.5.2 WinSight
WinSight 是一个用于查看Windows 对象并跟踪消息的发送和接收的调试工具。WinSight的图标可以在Delphi程序组中找到。
WinSight界面分为两部分,上面为对象树窗口,下面为消息跟踪窗口。如图12.9所示。
在实际应用中,用户可能只是对其中的一部分消息感兴趣,而又不希望它们淹灭在无用信息之中。为此,用户可以打开Message菜单并选择Selected Windows。按住Shift键,单击对象树窗口中感兴趣的对象,所选定对象的任何消息都显示在消息跟踪窗口中。
如果用户只想跟踪某些消息类,则打开Message菜单并选择Options ,使用如图12.10所示的检查框过滤消息。
12.6.6 小结
本章介绍的内容,核心是如何增强程序的健壮性并提高开发效率。为此我们首先考察了Delphi的异常处理机制,而后介绍了几种程序调试工具,在您即将结束基础篇的学习时,这些内容是您步入开发大型应用程序的高级程序员行列的必备武器。