Menu

#1850 TRACE issues

5.0.1
accepted
Erich
None
code+doc+test
1
2026-08-22
2022-11-21
Erich
No
END not traced

if execution of a SELECT instruction flows through a WHEN, the END instruction isn't traced.

rexx -e "trace r; select; when 1 then nop; otherwise; end"
     1 *-* select;
     1 *-*   when 1
       >>>     "1"
     1 *-*     then
     1 *-*       nop;

It execution flows through the OTHERWISE, the END instruction is traced as expected.

rexx -e "trace r; select; when 0 then nop; otherwise; end
     1 *-* select;
     1 *-*   when 0
       >>>     "0"
     1 *-*   otherwise
     1 *-* end
control variable not traced

A controlled repetitive loop doesn't trace control variable assignments.

rexx -e "trace r; do i = 1 to 2; end
     1 *-* do i = 1 to 2;
       >K>     "TO" => "2"
     1 *-* end
     1 *-* do i = 1 to 2;
     1 *-* end
     1 *-* do i = 1 to 2;

It should be traced like this:

     1 *-* do i = 1 to 2;
       >>>     "1"
     1 *-* end
     1 *-* do i = 1 to 2;
       >>>     "1"
       >>>     "2"
     1 *-* end
     1 *-* do i = 1 to 2;
       >>>     "2"
       >>>     "3"

Discussion

  • Erich

    Erich - 2023-03-11
    • status: open --> accepted
    • assigned_to: Erich
    • Pending work items: none --> code+doc+test
    • Group: None --> 5.0.1
     
  • Erich

    Erich - 2023-03-11

    Initial TRACE test group and some TRACE code fixes committed with revision [r12653]

    fixed bugs include:
    "trace i; a.t.t.t.t.t.t = 1" trace output has trailing question marks
    "forward message 'f' arguments(1, 2)" trace output is >K> "ARRAY"
    "forward message 'f' array(1, 2)" should trace >K> ARRAY
    "drop (list)" and "expose (list)" should trace indirect list
    "raise user 999 array(1, 2)" should trace >K> ARRAY

    bugs/quirks still pending include:
    trace; say trace() should be N, but is O; same for trace ''
    trace 2+3, trace (2+3), trace value 2+3 neither work as expected
    "raise user 999 description 'dddd'" should trace >K> DESCRIPTION
    "raise user 999 return 1" should trace >K> RETURN instead of RESULT
    "raise user 999 exit 1" should trace >K> EXIT instead of RESULT
    "trace i; .Array~new" should trace >M>
    "trace i; trace ??; say trace()" should not be nullstring

     

    Related

    Commit: [r12653]

  • Erich

    Erich - 2023-04-06

    committed more TRACE fixes with revision [r12662]
    added >R> trace flag documentation to rexxref with revision [r12663]

     

    Related

    Commit: [r12662]
    Commit: [r12663]

  • Erich

    Erich - 2023-04-06

    another fix committed with revision [r12664]

     

    Related

    Commit: [r12664]

  • Erich

    Erich - 2023-04-06

    corrected wrong [r12663] commit with [r12666]

     

    Related

    Commit: [r12663]
    Commit: [r12666]

  • Erich

    Erich - 2023-08-16

    DO/LOOP/SELECT no longer double-indent trace output
    Code fixes and test case updates committed with revision [r12719]

     

    Related

    Commit: [r12719]

  • Erich

    Erich - 2023-08-17

    TRACE test group fixes committed with revision [r12723]

     

    Related

    Commit: [r12723]

  • Moritz Hoffmann

    Moritz Hoffmann - 2026-08-22

    settings.traceIndent
    (interpreter/execution/ActivationSettings.hpp:188) is a mutable counter, not a computed property.
    newBlockInstruction increments it (interpreter/execution/RexxActivation.hpp:308) and DoBlock's
    constructor saves the pre-increment value (interpreter/instructions/DoBlock.cpp:71). The two exit
    paths from a loop disagree about how to undo that.

    • Normal termination goes RexxBaseBlockInstruction::terminate ->
      terminateBlockInstruction(doblock->getIndent())
      (interpreter/instructions/BaseDoInstruction.cpp:161), an absolute restore of the saved value
      (RexxActivation.hpp:306).
    • A failed control test goes RexxInstructionBaseLoop::endLoop
      (interpreter/instructions/BaseDoInstruction.cpp:377) -> popBlockInstruction() and then a bare
      unindent(), with no restore. unindent() clamps at zero (RexxActivation.hpp:318), and that
      clamp is why the defect is invisible at top level.

    Symptom. Any repetitive DO or LOOP that completes at least one body pass and then ends because
    its control test failed -- count exhausted, WHILE false, UNTIL true alike -- leaves the trace
    indent two columns low for every later clause. Zero-trip loops and loops left by LEAVE do not.
    Minimal reproducer, with no INTERPRET or CALL involved:

    do
    do jj = 1 to 1
    nop
    end
    say 1/0
    end
    

    The raise is printed at indent 0 where lexical depth is 2.

    Which enclosing constructs absorb the stray decrement rather than propagating it: exactly those
    that restore from a saved DoBlock -- any repetitive DO or LOOP, SELECT/OTHERWISE, and any
    DO carrying a LABEL, including a non-repetitive one, because
    interpreter/instructions/SimpleDoInstruction.cpp:78-89 creates the saved block only when a LABEL
    is present. An unlabelled plain DO propagates it outward, which is why the reproducer above uses
    one.

    State the mechanism rather than a rule about which constructs decrement. The behaviour is emergent
    from an imperative counter with inconsistent exit paths, and four separate attempts to state a
    declarative construct-by-construct rule here were each wrong.

     

Anonymous
Anonymous

Add attachments
Cancel