Menu

#31 $ZSTEP breaks if call (DO) is made during execution.

open
nobody
None
5
2015-02-20
2014-04-19
Bob Isch
No

There seems to be an inconsistancy, with the processing of $ZSTEP if a call is made during execution of $ZSTEP. Probably something to do with the stack level? Or, perhaps, I'm just not understanding how $ZSTEP is intended to work.

Thanks,
-bob

gtm30   ; Example of calling out of $zstep causing unexpected behavior.

; Invoke three times:
;       $ mumps -run A^gtm30
;       $ mumps -run B^gtm30
;       $ mumps -run C^gtm30
;
; On each run when the following error will be encountered at err+4:
;
;  %GTM-E-UNDEF, Undefined local variable: a
;                  At M source location err+4^gtm30
;
; Give a value to 'a':
;
;  GTM>s a=2
;
; Then continue to enter "zstep" commands until the routine exits back to the shell:
;
;  GTM>zstep
;   ...
;
; Note that the first two tests (A and B) require 8 zstep commands, but
; the last test (C) requires only 4 because breaks are not performed
; until an intervening QUIT command has executed.

; Also, note that the first "zstep" after assigning a value to 'a'
; does not result in actually executing any code in the routine (for
; any of the tests).  This probably demonstrates the normal behavior
; of zstep, however, it is not terribly intuitive.

; Entry Points:
A       d test("B") q
B       d test("w ""zstep-in> "",! b  w ""<zstep-out"",!") q
C       d test("d zsin b  d zsout") q

zsin    w "zstep-in> ",! q
zsout   w "<zstep-out",! q

test(zstep)     ; Perform one test.
        ;
        s $zstep=zstep
        ;
        w "test> "_$zversion_" - "_$zstep,!
        ;
        d err
        ;
        w "Exit test",!
        q  ; >>> test

err     ; For testing error handling/$ZSTEP
        ;
        w "err",!
        i 1 d
        .       w a,!
        .       w "foo",!
        .       w "bar",!
        ;
        w "Done",!
        q  ; >>> err

Sample output follows:

$ mumps -run 'A^gtm30'
test> GT.M V6.1-000 Linux x86_64 - B
err
%GTM-E-UNDEF, Undefined local variable: a
                At M source location err+4^gtm30

GTM>s a=2

GTM>zstep
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+4^gtm30

GTM>zstep
2
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+5^gtm30

GTM>zstep
foo
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+6^gtm30

GTM>zstep
bar
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+8^gtm30

GTM>zstep
Done
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+9^gtm30

GTM>zstep
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location test+8^gtm30

GTM>zstep
Exit test
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location test+9^gtm30

GTM>zstep
$

---------------------------------------------------------------------------
$ mumps -run 'B^gtm30'
test> GT.M V6.1-000 Linux x86_64 - w "zstep-in> ",! b  w "<zstep-out",!
err
%GTM-E-UNDEF, Undefined local variable: a
                At M source location err+4^gtm30

GTM>s a=2

GTM>zstep
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+4^gtm30

GTM>zstep
<zstep-out
2
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+5^gtm30

GTM>zstep
<zstep-out
foo
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+6^gtm30

GTM>zstep
<zstep-out
bar
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+8^gtm30

GTM>zstep
<zstep-out
Done
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+9^gtm30

GTM>zstep
<zstep-out
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location test+8^gtm30

GTM>zstep
<zstep-out
Exit test
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location test+9^gtm30

GTM>zstep
<zstep-out
$

----------------------------------------------------------------------------
$ mumps -run 'C^gtm30'
test> GT.M V6.1-000 Linux x86_64 - d zsin b  d zsout
err
%GTM-E-UNDEF, Undefined local variable: a
                At M source location err+4^gtm30

GTM>s a=2

GTM>zstep
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+4^gtm30

GTM>zstep
<zstep-out
2
foo
bar
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location err+8^gtm30

GTM>zstep
<zstep-out
Done
zstep-in>
%GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
                At M source location test+8^gtm30

GTM>zstep
<zstep-out
Exit test
$

Discussion

  • Bob Isch

    Bob Isch - 2014-04-19

    Actually, seems like it might be some sort of "line" oriented thing. Consider the following two additional cases:

    Code to be added to previous routine and invoked via entry points D and E:

    D  d test("d zsD") q
    E  d test("d zsE") q
    
    zsD   w "zstep-in> ",!  b  w "<zstep-out",!  q  ; >>> zsD
    
    zsE   ;
       w "zstep-in> ",!
       b
       w "<zstep-out",!
       q  ; >>> zsE
    

    The commands in the two "handlers" are identical but case "E" will never terminate unless a ZCONTINUE command is entered at some point instead of a ZSTEP. Entry point "D" actually exhibits desirable functionality except that the breakpoints are at zsD rather than the line being "stepped".

     
    • FIS GT.M Support

      Bob:

      Just a quick review:
      1) By default, zcontinuing from a ztrap'd line starts at the beginning of that line.
      2) zstep does an implied zcontinue that runs until a line matching the criteria is hit (this is the beginning of a line for zstep over ("over" is the default)).
      3) If $zstep contains a "do routinex" when the $zstep string is executed, routinex is placed on the stack (just as other do's would cause the routine to be placed on the stack).

      Let's consider the cases you had questions about below:
      Except for case A (which is the default behavior of $zstep) all of the other cases are variants of case B:

      B d test("w ""zstep-in> "",! b w ""<zstep-out"",!") q <-- note: $zstep will be assigned to the parameter passed to test

      Case C (writes are in separate routines):

      C d test("d zsin b d zsout") q
      zsin w "zstep-in> ",! q
      zsout w "<zstep-out",! q

      This case identified an issue where GT.M is not properly handling the line matching criteria when there is a "do" after the "break" (it seems to work fine with a "do" before the "break"). I have created a tracking number for this issue (GTM-8049). Thanks for identifying it.

      Case D (the original $zstep string is now in a routine which is called by the $zstep string):

      D d test("d zsD") q
      zsD w "zstep-in> ",! b w "<zstep-out",! q="" ;="">>> zsD

      From below:
      Entry point "D" actually exhibits desirable functionality except that the breakpoints are at zsD rather than the line being "stepped".

      From 3) above, this is expected since it was called by the xecution of the $zstep string (and the breakpoint is in that routine). The stack entry would be zsD^gtm30.

      Case E (Case D with the commands of the routine on separate lines):

      E d test("d zsE") q
      zsE ;
      w "zstep-in> ",!
      b
      w "<zstep-out",! q="" ;="">>> zsE

      From 1) and 2) above, when you do the first zstep the line matching criteria are met immediately and the executed $zstep string calls zsE which stops at the break at zsE+2^gtm30. Subsequent zsteps will result in recursive calls to zsE which will also stop at zsE+2^GT.M It is a recursive call since you are already in zsE.

      The reason case C does not result in recursive call is based upon 2) above. The zstep runs through the end of the line (which exits zsD) before xecuting $zstep which calls zsD.

      Thanks,
      Bill

       

Log in to post a comment.