在断点处中断执行。启用或禁用用户中断。
BREAK
的单点调试,指令 S
L
的区别。CTRL-C
的禁用用法。extend
与 flag
参数不能一起用。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
命令有三种形式:
注意:旧版本的Caché ObjectScript只接受Break命令的缩写(B)。当前版本接受这两种形式中的任何一种。
若要在运行代码时使用BREAK
语句,必须将用户分配给为%Development
资源提供U(使用)权限的角色(如%Developer
或%Manager
)。可以通过SQL GRANT语句或使用管理门户[主页]>[系统管理]>[用户]选项将用户分配给角色,以编辑用户的定义。
可选的后置条件表达式。如果后置条件表达式为TRUE(计算结果为非零数值),则Caché执行BREAK
命令。如果后置条件表达式为假(计算结果为零),则Caché不执行该命令。
Break Extension支持字母串代码来指定断点行为。双引号是必填项。
中断标志支持四种不同的方式来处理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
时会中断代码执行可以在程序源代码中使用无参数中断,带或不带后置条件,以在该点中断程序执行并将控制返回给终端提示符。无参数中断用于调试目的。
如果在例程中包含无参数中断,则会设置断点,从而中断例程执行并将进程返回到终端提示符。通过在代码中嵌入断点,可以建立用于调试的特定上下文。每次执行到中断时,Caché都会暂停例程并返回到终端提示符。然后可以使用其他ObjectScript命令执行调试活动。例如,可以使用WRITE
命令检查当前停止点处的变量值,使用SET
命令为这些或其他变量提供新值。还可以调用例程行编辑器(XECUTE^%
),它提供了修改例程的基本编辑功能。在以中断暂停例程执行后,可以使用无参数GOTO
恢复正常执行。或者,通过将此位置指定为GOTO
命令参数,可以在不同位置恢复执行。
注意:InterSystems建议使用ZBREAK
命令调用Caché Debugger,而不是在代码中使用Break
命令。调试器提供更广泛的调试功能。
可以使用%SYSTEM.Process
类的BreakMode()
方法为当前进程配置无参数中断行为。通过设置Config.Miscellous
类中的BreakMode
属性,可以在系统范围内配置无参数中断行为。
与所有无参数命令一样,必须在无参数分隔符和其后的同一行命令之间至少插入两个空格。
不必在要挂起例程的每个位置放置无参数中断命令。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 0
和BREAK 1
可用于创建代码块,其中CTRL-C信号不能中断关键命令序列。然而,交互式用户可能很难使用CTRL-C中断此类块上的循环。这是因为在检测CTRL-C陷阱和轮询CTRL-C信号之间存在轻微延迟。此延迟可允许下一个Break
命令循环解除CTRL-C用户中断。
包含BREAK 4
和BREAK 5
的程序块可用于创建代码,其中CTRL-C信号不能中断关键的命令序列,而不影响交互式用户使用CTRL-C中断该块上的循环操作的能力。
Break
的默认标志行为取决于登录模式,如下所示:
OPEN
或USE
命令中指定的B(/BREAK)
协议无效。为BREAK 0
。中断(如CTRL-C)由OPEN
或USE
命令中指定的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