To begin a debugging session on a specific routine, type the following command at the GTM prompt:

GTM>DO ^routinename

You can also begin a debugging session by pressing <CTRL-C> after running an M application at the shell. To invoke Direct Mode by pressing <CTRL-C>, process must have the Principal Device in the CENABLE state and not have the device set to CTRAP=$C(3).

When GT.M receives a <CTRL-C> command from the principal device, it invokes Direct Mode at the next opportunity, (usually at a point corresponding to the beginning of the next source line). GT.M can also interrupt at a FOR loop iteration or during a command of indeterminate duration such as LOCK, OPEN or READ. The GT.M USE command enables/disables the <CTRL-C> interrupt with the [NO]CENABLE deviceparameter. By default, GT.M starts <CTRL-C> enabled. The default setting for <CTRL-C> is controlled by $gtm_nocenable which controls whether <CTRL-C> is enabled at process startup. If $gtm_nocenable has a value of 1, "TRUE" or "YES" (case-insensitive), and the process principal device is a terminal, $PRINCIPAL is initialized to a NOCENABLE state where the process does not recognize <CTRL-C> as a signal to enter direct mode. No value, or other values of $gtm_nocenable initialize $PRINCIPAL with the CENABLE state. The [NO]CENABLE deviceparameter on a USE command can still control this characteristic from within the process.

GT.M displays the GTM> prompt on the principal device. Direct Mode accepts commands from, and reports errors to, the principal device. GT.M uses the current device for all other I/O. If the current device does not match the principal device when GT.M enters Direct Mode, GT.M issues a warning message on the principal device. A USE command changes the current device. For more information on the USE command, see Chapter 9: “Input/Output Processing.

The default "compile-as-written" mode of the GT.M compiler lets you run a program with errors as part of the debugging cycle. The object code produced includes all lines that are correct and all commands on a line with an error, up to the error. When GT.M encounters an error, it XECUTEs non empty values of $ETRAP or $ZTRAP. By default $ZTRAP contains a BREAK command, so GT.M enters Direct Mode.

The rest of the chapter illustrates the debugging capabilities of GT.M by taking a sample routine, dmex, through the debugging process. dmex is intended to read and edit a name, print the last and first name, and terminate if the name is an upper-case or lower-case "Q".

Each of the remaining sections of the chapter uses dmex to illustrate an aspect of the debugging process in GT.M.

To execute an M routine interactively, it is not necessary to explicitly compile and link your program. When you refer to an M routine that is not part of the current image, GT.M automatically attempts to compile and ZLINK the program.

Example:

GTM>DO ^dmex
Name: Revere, Paul
%GTM-E-UNDEF, Undefined local variable: bame
At M source location name+3^dmex
GTM>

In this example GT.M places you in Direct Mode, but also cites an error found in the program with a run-time error message. In this example, it was a reference to bame, which is undefined.

To see additional information about the error message, examine the $ECODE or $ZSTATUS special variables.

$ECODE is read-write intrinsic special variable that maintains a list of comma delimited codes that describe a history of past errors - the most recent ones appear at the end of the list. In $ECODE, standard errors are prefixed with an "M", user defined errors with a "U", and GT.M errors with a "Z". A GT.M code always follows a standard code.

$ZSTATUS is a read-write intrinsic special variable that maintains a string containing the error condition code and location of the last exception condition occurring during routine execution. GT.M updates $ZSTATUS only for errors found in routines and not for errors entered at the Direct Mode prompt.

[Note]Note

For more information on $ECODE and $STATUS see Chapter 8: “Intrinsic Special Variables.

Example:

GTM>WRITE $ECODE
,M6,Z150373850

This example uses a WRITE command to display $ECODE.

Example:

GTM>WRITE $ZS
150373850,name+3^dmex,%GTM-E-UNDEF, Undefined
local variable: bame

This example uses a WRITE command to display $ZSTATUS. Note that the $ZSTATUS code is the same as the "Z" code in $ECODE.

You can record the error message number, and use the $ZMESSAGE function later to re-display the error message text.

Example:

GTM>WRITE $ZM(150373850)
%GTM-E-UNDEF, Undefined local variable: !AD

This example uses a WRITE command and the $ZMESSAGE function to display the error message generated in the previous example. $ZMESSAGE() is useful when you have a routine that produces several error messages that you may want to examine later. The error message reprinted using $ZMESSAGE() is generic; therefore, the code !AD appears instead of the specific undefined local variable displayed with the original message.

When GT.M encounters a run-time or syntax error, it stops executing and displays an error message. GT.M reports the error in the message. In this case, GT.M reports an undefined local variable and the line in error, name+3^dmex. Note that GT.M re-displays the GTM> prompt so that debugging may continue.

To re-display the line and identify the error, use the ZPRINT command.

Example:

GTM>ZPRINT, name+3
%GTM-E-SPOREOL, Either a space or an end-of-line was expected but not found
ZP, name+3
^_____ 
GTM>

This example shows the result of incorrectly entering a ZPRINT command in Direct Mode. GT.M reports the location of the syntax error in the command line with an arrow. $ECODE and $ZSTATUS do not maintain this error message because GT.M did not produce the message during routine execution. Enter the correct syntax, (i.e., remove the comma) to re-display the routine line in error.

Example:

GTM>WRITE $ZPOS
name+3^dmex

This example writes the current line position.

$ZPOSITION is a read-only GT.M special variable that provides another tool for locating and displaying the current line. It contains the current entry reference as a character string in the format label+offset^routine, where the label is the closest preceding label. The current entry reference appears at the top of the M invocation stack, which can also be displayed with a ZSHOW "S" command.

To display the current value of every local variable defined, use the ZWRITE command with no arguments.

Example:

GTM>ZWRITE
ln=12
name="Revere, Paul"

This ZWRITE displays a listing of all the local variables currently defined.

[Note]Note

ZWRITE displays the variable name. ZWRITE does not display a value for bame, confirming that it is not defined.

The ZSTEP command provides a powerful tool to direct GT.M execution. When you issue a ZSTEP from Direct Mode, GT.M executes the program to the beginning of the next target line and performs the ZSTEP action.

The optional keyword portion of the argument specifies the class of lines where ZSTEP pauses its execution, and XECUTEs the ZSTEP action specified by the optional action portion of the ZSTEP argument. If the action is specified, it must be an expression that evaluates to valid GT.M code. If no action is specified, ZSTEP XECUTEs the code specified by the $ZSTEP intrinsic special variable; by default $ZSTEP has the value "B", which causes GT.M to enter Direct Mode.

ZSTEP actions, that include commands followed by a BREAK, perform the specified action, then enter Direct Mode. ZSTEP actions that do not include a BREAK perform the command action and continue execution. Use ZSTEP actions that issue conditional BREAKs and subsequent ZSTEPs to perform tasks such as test for changes in the value of a variable.

Use ZSTEP to incrementally execute a routine or a series of routines. Execute any GT.M command from Direct Mode at any ZSTEP pause. To resume normal execution, use ZCONTINUE. Note that ZSTEP arguments are keywords rather than expressions, and they do not allow indirection.

Example:

GTM>ZSTEP INTO
Break instruction encountered during ZSTEP action
At M source location print^dmex
GTM>ZSTEP OUTOF
Paul Revere
Name: Q
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
At M source location name^dmex
GTM>ZSTEP OVER
Break instruction encountered during ZSTEP action
At M source location name+1^dmex

This example shows using the ZSTEP command to step through the routine dmex, starting where execution was interrupted by the undefined variable error. The ZSTEP INTO command executes line name+3 and interrupts execution at the beginning of line print.

The ZSTEP OUTOF continues execution until line name. The ZSTEP OVER, which is the default, executes until it encounters the next line at this level on the M invocation stack. In this case, the next line is name+1. The ZSTEP OVER could be replaced with a ZSTEP with no argument because they do the same thing.

M DOs, XECUTEs, and extrinsics add a level to the invocation stack. Matching QUITs take a level off the stack. When GT.M executes either of these commands, an extrinsic function, or an extrinsic special variable, it "pushes" information about the new environment on the stack. When GT.M executes the QUIT, it "pops" the information about the discarded environment off the stack. It then reinstates the invoking routine information using the entries that have now arrived at the active end of the stack.

[Note]Note

In the M stack model, a FOR command does not add a stack frame, and a QUIT that terminates a FOR loop does not remove a stack frame.

The $STACK intrinsic special variable and the $STACK() function provide a mechanism to access M stack context information.

Example:

GTM>WRITE $STACK
2
GTM>WRITE $STACK(2,"ecode")
,M6,Z150373850,
GTM>WRITE $STACK(2,"place")
name+3^dmex
GTM>WRITE $STACK(2,"mcode")
if ln<30,bame?1.a.1"-".a1","1" "1a.ap do print q
GTM>

This example gets the value of $STACK and then uses that value to get various types of information about that stack level using the $STACK() function. The "ecode" value of the error information for level two, "place" is similar to $ZPOSITION, "mcode" is the code for the level.

In addition to the $STACK intrinsic special variable, which provides the current stack level, $STACK(-1) gives the highest level for which $STACK() can return valid information. Until there is an error $STACK and $STACK(-1) are the same, but once $ECODE shows that there is an "current" error, the information returned by $STACK() is frozen to capture the state at the time of the error; it unfreezes after a SET $ECODE="".

Example:

GTM>WRITE $STACK
2
GTM>WRITE $STACK(-1)
2
GTM>

This example shows that under the conditions created (in the above example), $STACK and $STACK(-1) have the same value.

The $STACK() can return information about lower levels.

Example:

+1^GTM$DMOD
GTM>WRITE $STACK(1,"ecode")
GTM>WRITE $STACK(1,"place")
beg^dmex
GTM>WRITE $STACK(1,"mcode")
beg for read !,"Name:",namde do name
GTM>

This example shows that there was no error at $STACK level one, as well as the "place" and "mcode" information for that level.

The ZSHOW command displays information about the M environment.

Example:

GTM>zshow "*"
$DEVICE=""
$ECODE=",M6,Z150373850,"
$ESTACK=2
$ETRAP=""
$HOROLOG="64813,21971"
$IO="/dev/pts/0"
$JOB=14550
$KEY=$C(13)
$PRINCIPAL="/dev/pts/0"
$QUIT=0
$REFERENCE=""
$STACK=2
$STORAGE=2147483647
$SYSTEM="47,gtm_sysid"
$TEST=1
$TLEVEL=0
$TRESTART=0
$X=0
$Y=26
$ZA=0
$ZALLOCSTOR=680360
$ZAUDIT=0
$ZB=$C(13)
$ZCHSET="M"
$ZCLOSE=0
$ZCMDLINE=""
$ZCOMPILE=""
$ZCSTATUS=0
$ZDATEFORM=0
$ZDIRECTORY="/path/to/the/current/directory"
$ZEDITOR=0
$ZEOF=0
$ZERROR="Unprocessed $ZERROR, see $ZSTATUS"
$ZGBLDIR="/path/to/the/global/directory"
$ZHOROLOG="64813,21971,720675,14400"
$ZICUVER=""
$ZININTERRUPT=0
$ZINTERRUPT="IF $ZJOBEXAM()"
$ZIO="/dev/pts/0"
$ZJOB=0
$ZKEY=""
$ZLEVEL=3
$ZMAXTPTIME=0
$ZMODE="INTERACTIVE"
$ZONLNRLBK=0
$ZPATNUMERIC="M"
$ZPIN="/dev/pts/0"
$ZPOSITION="name+5^dmex"
$ZPOUT="/dev/pts/0"
$ZPROMPT="GTM>"
$ZQUIT=0
$ZREALSTOR=697936
$ZRELDATE="20180614 00:33"
$ZROUTINES=". /usr/lib/fis-gtm/V6.3-005_x86_64 /usr/lib/fis-gtm/V6.3-005_x86_64/plugin/o(/usr/lib/fis-gtm/V6.3-005_x86_64/plugin/r)"
$ZSOURCE=""
$ZSTATUS="150373850,name+5^dmex,%GTM-E-UNDEF, Undefined local variable: bame"
$ZSTEP="B"
$ZSTRPLLIM=0
$ZSYSTEM=0
$ZTIMEOUT=-1
$ZTDATA=0
$ZTDELIM=""
$ZTEXIT=""
$ZTLEVEL=0
$ZTNAME=""
$ZTOLDVAL=""
$ZTRAP="B"
$ZTRIGGEROP=""
$ZTSLATE=""
$ZTUPDATE=""
$ZTVALUE=""
$ZTWORMHOLE=""
$ZUSEDSTOR=671689
$ZUT=1528970771720738
$ZVERSION="GT.M V6.3-005 Linux x86_64"
$ZYERROR=""
ln=8
name="John Doe"
/dev/pts/0 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=165 LENG=48
MLG:0,MLT:0
GLD:*,REG:*,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0
DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,TTR:0,TRB:0,TBW:0,
TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0,ZTR:0,DFL:0,
DFS:0,JFL:0,JFS:0,JBB:0,JFB:0,JFW:0,JRL:0,JRP:0,JRE:0,JRI:0,JRO:0,JEX:0,DEX:0,
CAT:0,CFE:0,CFS:0,CFT:0,CQS:0,CQT:0,CYS:0,CYT:0,BTD:0
name+5^dmex    ($ZTRAP)
    (Direct mode)
beg+1^dmex:51a6a6c4739b004094c4545246ce4d68
+1^GTM$DMOD    (Direct mode)
GTM>

This example uses the asterisk (*) argument to show all information that ZSHOW offers in the context debugging the error in the ^dmex routine. First are the Intrinsic Special Variables ($DEVICE-$ZYERROR, also available with ZSHOW "I"), then the local variables (bame, ln and name, also available with ZSHOW "V"), then the ZBREAK locations (name+3^dmex, also available with ZSHOW "B"), then the device information (also available with ZSHOW "D"), then the M stack (also available with ZSHOW "S"). ZSHOW "S" is the default for ZSHOW with no arguments.

Context information that does not exist in this example includes M LOCKs of this process (ZSHOW "L").

In addition to directing its output to the current device, ZSHOW can place its output in a local or global variable array. For more information, see the command description “ZSHow”.

[Note]Note

ZSHOW "V" produces the same output as ZWRITE with no arguments, but ZSHOW "V" can be directed to a variable as well as a device.

The ZGOTO command transfers control from one part of the routine to another, or from one routine to another, using the specified entry reference. The ZGOTO command takes an optional integer expression that indicates the M stack level reached by performing the ZGOTO, and an optional entry reference specifying the location to where ZGOTO transfers control. A ZGOTO command, with an entry reference, performs a function similar to the GOTO command with the additional capability of reducing the M stack level. In a single operation, the process executes $ZLEVEL-intexpr, implicit QUITs from DO or extrinsic operations, and a GOTO operation transferring control to the named entry reference.

The ZGOTO command leaves the invocation stack at the level of the value of the integer expression. GT.M implicitly terminates any intervening FOR loops and unstacks variables stacked with NEW commands, as appropriate.

ZGOTO $ZLEVEL:LABEL^ROUTINE takes the same action as GO LABEL^ROUTINE.

ZGOTO $ZLEVEL-1 produces the same result as QUIT (followed by ZCONTINUE, if in Direct Mode).

If the integer expression evaluates to a value greater than the current value of $ZLEVEL, or less than zero (0), GT.M issues a run-time error.

If ZGOTO has no entry reference, it performs some number of implicit QUITs and transfers control to the next command at the specified level. When no argument is specified, ZGOTO 1 is the result, and operation resumes at the lowest level M routine as displayed by ZSHOW "S". In the image invokedby mumps -direct, or a similar image, a ZGOTO without arguments returns the process to Direct Mode.

Use the ZLINK command to add the edited routine to the current image. ZLINK automatically recompiles and relinks the routine. If the routine was the most recent one ZEDITed or ZLINKed, you do not have to specify the routine name with the ZLINK command.

[Caution]Caution

When you issue a DO command, GT.M determines whether the routine is part of the current image, and whether compiling or linking is necessary. Because this routine is already part of the current image, GT.M does not recompile or relink the edited version of the routine if you run the routine again without ZLINKing it first. Therefore, GT.M executes the previous routine image and not the edited routine.

[Note]Note

You may have to issue a ZGOTO or a QUIT command to remove the unedited version of the routine from the M invocation stack before ZLINKing the edited version.

Example:

GTM>ZLINK
 Cannot ZLINK an active routine

This illustrates a GT.M error report caused by an attempt to ZLINK a routine that is part of the current invocation stack.

To ZLINK the routine, remove any invocation levels for the routine off of the call stack. You may use the ZSHOW "S" command to display the current state of the call stack. Use the QUIT command to remove one level at a time from the call stack. Use the ZGOTO command to remove multiple levels off of the call stack.

Example:

GTM>ZSHOW "S"
name+3^dmex ($ZTRAP) (Direct mode)
beg^dmex (Direct mode)
 ^GTM$DMOD (Direct mode)
GTM>ZGOTO
GTM>ZSHOW "S"
 ^GTM$DMOD (Direct mode)
GTM>ZLINK

This example uses a ZSHOW "S" command to display the current state of the call stack. A ZGOTO command without an argument removes all the calling levels above the first from the stack. The ZLINK automatically recompiles and relinks the routine, thereby adding the edited routine to the current image.

loading table of contents...