第一章 Caché 命令大全 BREAK 命令

第一章 Caché 命令大全 BREAK 命令

在断点处中断执行。启用或禁用用户中断。

重点

  1. BREAK的单点调试,指令 S L的区别。
  2. CTRL-C的禁用用法。
  3. extendflag 参数不能一起用。
  4. InterSystems建议使用ZBREAK命令

大纲

BREAK:pc "extend"
B:pc "extend"

BREAK:pc flag
B:pc flag

参数

代码 描述
pc 可选-后置条件表达式。
extend 可选-指示要启用或禁用的断点类型的字母代码,以带引号的字符串形式指定。有效值列在中断扩展参数中。不能与flag参数一起使用。
flag 可选-指定中断行为的整数标志。标志值可以加引号,也可以不加引号。有效值为:0和4,用于禁用CTRL-C中断;1和5,用于启用CTRL-C中断。默认值由上下文确定。不能与extend参数一起使用。

描述

BREAK命令有三种形式:

  • 不带参数的Break会中断当前位置的代码执行。
  • Break Extension以定期断点间隔中断代码执行。
  • BREAK flag 启用或禁用CTRL-C中断。

注意:旧版本的Caché ObjectScript只接受Break命令的缩写(B)。当前版本接受这两种形式中的任何一种。

所需权限

若要在运行代码时使用BREAK语句,必须将用户分配给为%Development资源提供U(使用)权限的角色(如%Developer%Manager)。可以通过SQL GRANT语句或使用管理门户[主页]>[系统管理]>[用户]选项将用户分配给角色,以编辑用户的定义。

参数

pc

可选的后置条件表达式。如果后置条件表达式为TRUE(计算结果为非零数值),则Caché执行BREAK命令。如果后置条件表达式为假(计算结果为零),则Caché不执行该命令。

extend

Break Extension支持字母串代码来指定断点行为。双引号是必填项。

flag

中断标志支持四种不同的方式来处理CTRL-C中断:

  • BREARK 0:解除任何挂起但尚未发出信号的CTRL-C陷阱。禁用CTRL-C的未来信号。
  • BREARK 1:取消任何挂起的CTRL-C陷阱。启用CTRL-C的未来信令。这意味着在执行Break 1之后键入CTRL-C会导致CTRL-C信号。
  • BREARK 4:不取消任何挂起的CTRL-C陷阱。禁用CTRL-C的未来信号。这意味着当将来的中断1或中断5命令启用CTRL-C时,将发出挂起CTRL-C陷阱的信号。
  • BREARK 5:不清除任何挂起的CTRL-C陷阱。启用CTRL-C的未来信令。这意味着挂起的CTRL-C陷阱应该在中断5之后不久由Caché ObjectScript命令发出信号。大多数(但不是所有Caché ObjectScript命令轮询CTRL-C。

无参Break

遇到 无参 Break时会中断代码执行可以在程序源代码中使用无参数中断,带或不带后置条件,以在该点中断程序执行并将控制返回给终端提示符。无参数中断用于调试目的。

如果在例程中包含无参数中断,则会设置断点,从而中断例程执行并将进程返回到终端提示符。通过在代码中嵌入断点,可以建立用于调试的特定上下文。每次执行到中断时,Caché都会暂停例程并返回到终端提示符。然后可以使用其他ObjectScript命令执行调试活动。例如,可以使用WRITE命令检查当前停止点处的变量值,使用SET命令为这些或其他变量提供新值。还可以调用例程行编辑器(XECUTE^%),它提供了修改例程的基本编辑功能。在以中断暂停例程执行后,可以使用无参数GOTO恢复正常执行。或者,通过将此位置指定为GOTO命令参数,可以在不同位置恢复执行。

注意:InterSystems建议使用ZBREAK命令调用Caché Debugger,而不是在代码中使用Break命令。调试器提供更广泛的调试功能。

可以使用%SYSTEM.Process类的BreakMode()方法为当前进程配置无参数中断行为。通过设置Config.Miscellous类中的BreakMode属性,可以在系统范围内配置无参数中断行为。

与所有无参数命令一样,必须在无参数分隔符和其后的同一行命令之间至少插入两个空格。

BREAK Extended 参数以设置常规断点

不必在要挂起例程的每个位置放置无参数中断命令。Break有一系列“扩展”参数(EXTEND),它们可以周期性地挂起例程,就像在整个代码中散布无参数中断一样。

下表列出了BREAK命令扩展参数。

代码 描述
"S" 使用Break “S”(单步)一次单步执行代码中的一个命令(生成的令牌)。并不是所有的ObjectScript命令都会生成一个令牌;有些命令会生成多个令牌,因此会被解析为多个步骤(见下文)。Caché停止中断由DO命令或XECUTE命令调用的命令,或在FOR循环或用户定义函数内中断,并在命令或循环完成时使用下一个令牌继续。逐步,不进方法,不进入循环。
"S+" Break “S+”的作用与Break“S”相似,不同之处在于Caché包括DO命令或XECUTE命令调用的命令上的中断,或者在for循环或用户定义函数内的中断。逐渐过程,进循环。
"S-" 使用BREAK “S-”在当前级别禁用中断步进(“S”“L”),并在上一级别启用单步进。作用类似于在当前级别中断“C”和在上一级别中断“S”中断,逐步,逐过程。
"L" 使用Break “L”(行步进)单步执行代码,每次单步执行一个例程行,在每行开始处中断。不生成令牌的行将被忽略(见下文)。Caché停止中断由DO命令或XECUTE命令调用的命令,或在FOR循环或用户定义函数内中断,并在命令或循环完成时从下一行继续。逐步,不进方法,不进入循环。
"L+" Break “L+”的作用类似于Break“L”,不同之处在于,在DO命令或XECUTE命令调用的命令上,或者在for循环或用户定义函数内,Caché还会在每个例程行的开头继续中断。逐渐过程,进循环。
"L-" 使用BREAK“L-”在当前级别禁用中断步进(“S”“L”),并在上一级别启用行步进。类似于在当前级别中断“C”和在上一级别中断“L”中断,逐步,逐过程。
"C" 使用BREAK “C”(清除BREAK)在当前级别停止所有中断步进(“L”“S”)。如果中断状态在上一例程级别生效,则在作业执行退出后,中断在该例程级别恢复。
"C-" 使用BREAK “C-”停止当前级别和所有以前级别的所有中断步进(“L”“S”)。这允许在所有级别移除单步执行,而不会影响其他调试功能。
"OFF" BREAK "OFF"删除已为进程建立的所有调试。它删除所有断点和观察点,并关闭所有程序堆栈级别的单步执行。它还会删除与调试和跟踪设备的关联,但不会关闭它们。

在生成标记的语句上BREAK “S”BREAK “L” 。并非所有ObjectScript命令或行都会生成令牌。例如,BREAK “S”BREAK “L”都忽略标签行、注释和Try语句。BREAK “S”CATCH语句处中断(如果输入了CATCH块);中断“L”不会。

BREAK “S”BREAK “L”之间的一个不同之处在于,许多命令行生成一个以上的标记,因此由一个以上的步骤组成。例如,下面都是一行(和一个ObjectScript命令),但Break“S”将每个步骤解析为两个步骤: SET x=1,y=2, KILL x,y, WRITE “hello”,!, IF x=1,y=2.

BREAK “S”BREAK “L” 更加细致。

要在断点之后恢复代码执行,请在终端提示符下发出GOTO命令。

发出 BREAK "OFF"命令相当于发出以下一系列命令:

  ZBREAK /CLEAR
  ZBREAK /TRACE:OFF
  ZBREAK /DEBUG:""
  ZBREAK /ERRORTRAP:ON
  BREAK "C-"

启用或禁用中断的中断标志

使用中断标志控制用户中断(如CTRL-C)是启用还是禁用。这些禁用/启用选项之间的实际区别如下:

BREAK 0BREAK 1可用于创建代码块,其中CTRL-C信号不能中断关键命令序列。然而,交互式用户可能很难使用CTRL-C中断此类块上的循环。这是因为在检测CTRL-C陷阱和轮询CTRL-C信号之间存在轻微延迟。此延迟可允许下一个Break命令循环解除CTRL-C用户中断。

包含BREAK 4BREAK 5的程序块可用于创建代码,其中CTRL-C信号不能中断关键的命令序列,而不影响交互式用户使用CTRL-C中断该块上的循环操作的能力。

Break的默认标志行为取决于登录模式,如下所示:

  • 如果在终端提示符下登录,则默认为中断1。中断(如CTRL-C)始终处于启用状态。在OPENUSE命令中指定的B(/BREAK)协议无效。
  • 如果在例程中,则默认值为BREAK 0。中断(如CTRL-C)由OPENUSE命令中指定的B(/BREAK)协议启用或禁用。

中断标志示例

以下示例使用$ZJOB确定是启用还是禁用中断:

/// d ##class(PHA.TEST.ObjectScript).TestBreak1()
ClassMethod TestBreak1()
{
 BREAK 0
    DO InterruptStatus
 BREAK 1
    DO InterruptStatus
    WRITE "all done"
InterruptStatus()
  IF $ZJOB\4#2=1 {WRITE "Interrupts enabled",!}
  ELSE {WRITE "Interrupts disabled",!}
}
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestBreak1()
Interrupts disabled
Interrupts enabled
all done

下面的示例使用for循环中的读取操作来输入一系列数字。它设置BREAK 0以禁用读取操作期间的用户中断。但是,如果用户输入的值不是数字,则中断1会启用用户中断,以便用户可以拒绝或接受他们刚刚输入的值:

/// d ##class(PHA.TEST.ObjectScript).TestBreak2()
ClassMethod TestBreak2()
{
	  SET y="^" 
InputLoop
  TRY {
      FOR {
           BREAK 0
           READ "输入一个数字 ",x
           IF x="" { WRITE !,"all done"  QUIT }
           ELSEIF 0=$ISVALIDNUM(x) {
             BREAK 1
             WRITE !,x," 不是一个数字 ",!
             WRITE "你有4秒可以按 CTRL-C",!
             WRITE "或接受这个值",!
             HANG 4 }
           ELSE {  }
           SET y=y_x_"^"
           WRITE !,"数字数组是 ",y,!
      }
   }
   CATCH { WRITE "拒绝错误输入",!
           DO InputLoop
   }
}
用户名:yx
密码:******
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestBreak2()
输入一个数字 1
数字数组是 ^1^
输入一个数字 2
数字数组是 ^1^2^
输入一个数字 3
数字数组是 ^1^2^3^
输入一个数字 4
数字数组是 ^1^2^3^4^
输入一个数字 5
数字数组是 ^1^2^3^4^5^
输入一个数字 a
a 不是一个数字
你有4秒可以按 CTRL-C
或接受这个值
 
数字数组是 ^1^2^3^4^5^a^
输入一个数字 2
数字数组是 ^1^2^3^4^5^a^2^
输入一个数字
all done

猜你喜欢

转载自blog.csdn.net/yaoxin521123/article/details/107076647