Delphi应用程序的调试(三)监视变量

监视变量(Watching Variables)

当程序停在一个断点处时,用户做些什么呢?通常用户在断点处停下来是要检查变量的值,某个变量的值是否与预料的取值相同?或者某个变量取什么值(事先并不知道这个变量的取值)。

Watch List窗口的作用是使用户能检查变量的值。编程人员常常忽视这个简单而又根本的特性,因为他们没有花时间来完整地学习调试器的使用。用户可添加任意多的变量到Watch List中。下图就是调试会话期间的Watch List窗口。

变量名和变量值都显示在Watch List中。

Tooltip表达式求值(Tooltip Expression Evaluation)

调试器和Code Editor有一个很好的特性,它使检查变量值的工作变得更容易。这个特性就是Tooltip表达式求值器(expression evaluator),其缺省状态是打开,因此用户不需要做任何事情就能使用它。如果需要,也可以通过Editor Properties对话框的Code Insight页面来关闭它,如下图:

那么,什么是Tooltip表达式求值呢?它是这样工作的:当程序停在一个断点处,用户把编辑光标移到一个变量上,就会弹出一个提示窗口,其中显示该变量的当前值。这样就使快速检查变量的工作变得更容易,只需将光标移到变量上并稍等片刻。

Tooltip evaluator求值器对于不同的变量类型由不同的显示。对于常规数据成员(Integer、Char、Byte、String等等),显示变量的实际值;对于动态创建的对象(例如一个类的实例),Tooltip evaluator显示记录的全部元素。如下图所示:

Note

有时候Tooltip evaluator好像工作不正常。例如,若将编辑光标移到一个作用域外的变量上时,就不会显示提示窗口,因为Tooltip evaluator 无任何信息可显示。被编辑器优化过的变量也可能不能显示正确值。

当光标位于with块中时,Tooltip evaluator也不工作。例如,看下面这段代码:


1

2

3

4

5

6

7

8

9

10

11

var

  pp: Point;

begin

  with  pp do

  begin

    x := 20;

    y := 40;

  end;

  Caption := IntToStr(pp.x);

end;

如果把光标放到变量x上,Tooltip evaluator不会显示x的值,因为x属于with语句(Point变量)。如果将光标移到变量Point上,调试器会显示Point的值(包括x字段)。如下图:

Tooltip 表达式求值器很有用的,别忘记使用它。

Watch List快捷菜单(The Watch List Context Menu)

正如前面讲到的每一个Delphi窗口一样,Watch List也有它自己的快捷菜单。如下描述:

Edit Watch——打开Watch Properties对话框修改监视项属性 
Add Watch——打开Watch Properties对话框新监视项 
Enable Watch——启用一个已经禁用的监视项 
Disable Watch——禁用一个已启用的监视项 
Delete Watch——删除一个监视项 
Enable All Watches——启用所有已经禁用的监视项 
Disable All Watches——禁用所有已经启用的监视项 
Delete All Watches——删除所有监视项 
Add Group——增加一个监视组 
Delete Group——删除一个监视组 
Move Watch to Group——移动监视项到组 
Stay On Top——使Watch List窗口始终在最上层

Inspect——显示选中的监视项的有关信息 
Break When Changed——当监视窗口中的变量改变时,调试器将终端。监视变量以红色显示,表示Break When Changed起作用。 
Dockable——窗口是可泊位。

使用Watch Properties对话框(Using the Watch Properties Dialog Box)

当用户增加或编辑监视项时,要使用Watch Properties对话框。如上图显示的是正在编辑pp变量的Watch Properties对话框。

位于对话框顶部的【Expression字段】,是用户输入要编辑或增加到Watch List中的变量名的地方,这个字段是一个组合框,可以用来选取以前用过的监视项。

但用户要检查数组时,使用【Repeat count字段】,比如,有一个20个整数元素的数组,要检查数组的头10个整数,可在【Expression字段】中输入数组的第一个元素(例如Array[0]),再在【Repeat count字段】中输入10。数组的头10个元素就会显示在Watch List中。如下图pp为有20个元素的整型数组:

Note

如果将数组名增加到Watch List中,则数组的全部元素都会显示在Watch List中。当要查看数组的部分元素时,使用【Repeat count字段】。

仅当检查浮点数时,采使用【Digits字段】;在此输入显示浮点数时要显示的有效位数,有效位后面的余数作四舍五入处理。【Enabled字段】确定监视项是否当前启用。

Watch Properties对话框上的其余选项都是显示选项。每一种数据类型都有一种缺省显示类型,当用户选中【Default】时,就使用缺省显示类型,Default查看选项的默认状态时“选中”的。选择其他的查看选项,就以其他方式查看数据。如下图:

要修改一个监视项,可在Watch List中点击该项,然后在右键快捷菜单中选择【Edit Watch…】菜单项,也可双击该监视项,快速打开Watch Properties对话框。

启用和禁用监视项(Enabling and Disabling Watch Items)

就像使用断点时一样,Watch List中每项都可被启用或禁用。当一个监视项被禁用时,它会变灰,并且它的值显示为<disabled>。如下图:

要禁用一个监视项,可点击Watch List中该项的名字,并从Watch List快捷菜单中选择【Disabled Watch】菜单项;要启用该监视项,就从快捷菜单中选【Enabled Watch】菜单项。

Note

用户可能希望禁用当前不使用但以后要使用的监视项。在调试过程中,Watch List中的许多有效监视项会减慢程序执行速度,因为每当一个代码行执行时,所有Watch List变量都要更新。

向Watch List中添加变量(Adding Variables to the Watch List)

可用多种方法往Watch List中添加监视项。最快速的方法是点击Code Editor中的变量名,然后从Code Editor的快捷菜单中选择【Debug | Add Watch at Cursor】或按【Ctrl + F5】键,该监视项就会被立即增加到Watch List中。如果需要,用户可以编辑该监视项,修改其属性。

要增加一个变量到Watch List中而又不想在源文件中找出该变量时,可从主菜单选择【Run | Add Watch】菜单项;当Watch Properties对话框弹出后,输入要增加到Watch List中的变量名并点击OK。

Note

虽然可将类实例变量添加到Watch List中,但显示的值可能无用。如下图:

应该使用Debug Inspector查看类的所有数据成员。

使用Watch List(Using the Watch List)

当碰到断点时,Watch List显示其中所有变量的当前值,如果当前没有打开Watch List窗口,可从主菜单【View | Debug Window | Watches】菜单项打开Watch List窗口。

Note

将Watch List窗口泊位到Code Editor窗口的底部,这样,在调试代码时,总可以看到它。

在某些情况下,Watch List中变量的后面会显示一条消息,而不是该变量的值。例如,如果一个变量不在作用域之外,或未找到,Watch List在该变量名后面显示“Undeclared identifier: ‘X’”;如果程序没有运行或不停在断点处,Watch List在所有的监视项后都显示[process not accessible]。禁用监视项后显示<disabled>。根据应用程序的当前状态或某个变量的当前状态,还可能显示其他消息。

就像上一章提到过的,用户在Watch List中偶尔会看到这样的显示:variable ‘X‘ inaccessible here due to optimization,这是带优化功能的编辑器的一个小缺点。如果要检查易被优化的变量,则必须关闭编译器的优化功能,即把Project Options对话框中的Compiler页面上的Optimization选项关闭。

未被初始化的变量会显示随机值,直到它被初始化。

Note

Watch List可用作一个简单的十进制/十六进制转换器。要把一个十六进制数转换成十进制数,可从主菜单选择【Run | Add Watch】,在Expression字段输入十六进制数后点击OK,输入的十六进制数和与之等价的十进制数就会显示在Watch List中;要将一个十进制数转换成十六进制数,除点击Hexadecimal单选钮将显示类型改为十六进制外,其余操作都与前面相同。由于Expression接受数学表达式,因此还可以把Watch List当做一个十六进制计算器,甚至可以在同一个表达式中同时使用十六进制和十进制值。如下图:

这样使用Watch List只有一个缺点,应用程序必须停在一个断点处

在调试应用程序的过程中,Watch List是一个简单而又关键的工作。为了说明Watch List的使用,接下来做一个练习:

1)创建一个应用程序,在其主窗体上放置一个按钮。将按钮的Name属性设置为WatchBtn,Caption属性改为Watch Test。将主窗体Name属性改为DebugMain,Caption属性改为Debug Watch List Test。

2)双击按钮,会在Code Editor中显示按钮的OnClick处理事件,按下面的样子修改其OnClick处理程序:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

procedure TDebugMain.WatchBtnClick(Sender: TObject);

var

  S: string;

  X, Y: Integer;

begin

  X := Width;

  S := IntToStr(X);

  Y := Height;

  X := X * Y;

  S := IntToStr(X);

  X := X div Y;

  S := IntToStr(X);

  Width := X;

  Height := Y;

end;

3)保存该工程,将单元命名为DbgMain,工程命名为DebugTest。

4)在OnClick处理程序的begin语句之后的第一行上设置一个断点,运行该应用程序。

5)点击Watch Test按钮,调试器会停止在断点处。当调试器停在断点处时,IDE和Code Editor会显示在最顶层。

6)把变量S,X和Y增加到Watch List中(由于代码优化,变量X和变量Y在开始时是不可访问的),如下图:

7)安排好Watch List和Code Editor的位置,以便用户能同时看到两个窗口(不妨把Watch List泊位到Code Editor的底部)。

8)将输入焦点切换到Code Editor,并按F8执行下一行代码,执行完毕后,执行点移到下一行。此时Watch List中变量X显示一个值。如下图:

9)按F8继续一行一行执行程序,监视Watch List中变量的结果。

10)当执行点到达OnClick处理程序的最后一行时,点击工具栏中的Run按钮继续运行应用程序。

用户可反复点击Watch Test按钮来体会Watch List是如何工作的,每次还可试验不同监视设置的效果。

Note

在上面的例子中,OnClick处理程序先获取主窗体的Width属性和Height属性的值,接着执行一些计算,然后再将Width和Height设置成开始时的值。这段程序执行完后,什么都未发生改变。在该方法末尾给Width和Height属性赋值是有原因的。

如果在代码中不真正使用变量X和Y的话,用户就不能检查这两个变量,因为编译器在优化代码时会发现这个两个变量未被使用,从而将它们删除。在方法的末尾使用这两个变量就是为了避免编译器把它们优化掉。

前面提到过这个问题,希望大家对带优化功能的编译器的工作过程有个基本了解。这样,当开始调试应用程序,碰到诸如“Variable ‘Y’ inaccessible here due to optimization”一类的消息时就不会不知所措。

以上代码均在Delphi7中测试通过,实例代码下载:WatchList测试程序.rar

原文地址:https://www.cnblogs.com/m0488/p/9533403.html

时间: 2024-10-09 12:12:55

Delphi应用程序的调试(三)监视变量的相关文章

Delphi应用程序的调试

Delphi应用程序的调试(一) Delphi应用程序的调试(二)使用断点 Delphi应用程序的调试(三)监视变量 Delphi应用程序的调试(四)The Debug Inspector Delphi应用程序的调试(五)其他调试工具 Delphi应用程序的调试(六)步进式代码调试 Delphi应用程序的调试(七)调试DLL Delphi应用程序的调试(八)事件日志窗口和模块窗口 Delphi应用程序的调试(九)调试技术 Delphi应用程序的调试(十)调试器选项

Delphi应用程序的调试(二)使用断点

Delphi应用程序的调试(二)使用断点 使用断点(Using Breakpoints) 当用户从Delphi IDE 运行程序时,程序全速运行,只会在设置了断点的地方停住. New Term 断点(breakpoint)是一种标记,用以通知编译器,当程序运行到断点所在位置时暂停程序的执行. 设置和清除断点(Setting and Clearing Breakpoints) 断点的设置可通过点击Code Editor的沟槽来进行:要在代码的某一行暂停程序执行,就在沟槽中与该行相对应的位置上点击鼠

Delphi应用程序的调试(五)其他调试工具

Delphi应用程序的调试(五)其他调试工具 Delphi7中提供了一些附加调试工具来帮助用户检查程序错误.从性能上讲,其中一些工具属于高级调试工具.尽管高级调试工具不像其他工具那样常用,但对于经验丰富的编程人员来说,它们是非常有用的. Evaluate/Modify对话框(The Evaluate/Modify Dialog Box) 该对话框用于检查变量的当前值和修改变量的值.使用这个对话框,用户可以修改某个变量的值来测试不同的输出结果.在调试期间改变一个变量的值,使用户能测试程序不同参数的

Delphi应用程序的调试(一)

集成式调试器是Delphi IDE的一个重要特性.该调试器使用户能方便地设置断点.监视变量.检查对象等等.在运行程序时,使用该调试器能快速查找出程序发生了什么(或未发生什么).一个号的调试器对程序开发的效率至关重要. 调试工作容易被忽略.我也是刚开始学习Windows编程时,很长时间都未理睬调试器,因为当时忙于学习如何编写Windows应用程序.当后来知道这是一个很有价值的调试器的后,才后悔为什么没有早点使用它.希望大家从我的经历中吸取教训. 一.为什么使用调试器 对于这个问题的回答很简单:调试

Delphi应用程序的调试(十)调试器选项(在IDE中不要使用异常)

可在两个级别上设置调试选项:工程级和环境级.在前面的讲解中讲解了工程级调试选项,通过主菜单[Project | Options…]打开如下对话框: 可在Debugger Options对话框中设置全局级调试选项.从主菜单[Tools | Debugger Options]菜单项调出Debugger Options对话框. 在Debugger Options对话框的底部有一个标记为Integrated debugging的复选框,它控制是否使用IDE调试器调试程序.如果选中Integrated d

Delphi应用程序的调试(十)调试器选项

可在两个级别上设置调试选项:工程级和环境级.在前面的讲解中讲解了工程级调试选项,通过主菜单[Project | Options…]打开如下对话框: 可在Debugger Options对话框中设置全局级调试选项.从主菜单[Tools | Debugger Options]菜单项调出Debugger Options对话框. 在Debugger Options对话框的底部有一个标记为Integrated debugging的复选框,它控制是否使用IDE调试器调试程序.如果选中Integrated d

Visual Studio断点调试, 无法监视变量, 提示无法计算表达式

在使用Visual Studio 2012进行断点调试时,对某个变量添加监视,出现"无法计算表达式"的提示. 解决办法:依次点击菜单栏中的"调试"→"图形"→"启动诊断" 期间会出现类似如下界面: 公共符号下载完毕,断点调试,变量监视功能恢复正常!

01.程序的调试

断点调试: 程序的调试对于程序开发而言特别重要. (1).写完一段程序之后,想看一下这段程序的执行过程. (2).当你写完这段程序之后,发现,程序并没有按照你的想象的样子去执行. 调试方法: (1).F11逐语句调试(单步调试) (2).F10逐过程调试 (3).断点调试 调试时,被标黄的代码时提示我们这段代码还没有被执行,但是它将要被执行. 我们可以在监视窗口下,查看变量,以及表示式值的运行情况. 当我们发现监视窗口下的值变成了红色,说明这个值刚刚发生了改变. 进行断点调试的时候,程序会运行到

[转] python程序的调试方法

qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python def debug_demo(val): if val <= 1600 : print "level 1" print 0 elif val <= 3500 : print "level 2" print (val - 1600) * 0.05 elif val