REXX debugger - REXX

This is a discussion on REXX debugger - REXX ; Back in the day, there used to be an IBM Employee Written Software (EWS) REXX debugger. It ran on OS/2, and was fairly limited--especially since it was a 16-bit app compiled with the small memory model...but I digress. I have ...

+ Reply to Thread
Page 1 of 3 1 2 3 LastLast
Results 1 to 10 of 27

REXX debugger

  1. Default REXX debugger

    Back in the day, there used to be an IBM Employee Written Software (EWS)
    REXX debugger. It ran on OS/2, and was fairly limited--especially since
    it was a 16-bit app compiled with the small memory model...but I digress.

    I have a big-iron clusterized electromagnetic simulator that consists of
    two C++ programs, the clusterized number cruncher and a single-threaded
    postprocessor, and a fairly gigantic REXX script that understands a nice
    human-friendly command language and runs all the rest, including
    generating DXF files of the simulation geometry, doing optimization, and
    so forth. It works very well--it's fast and powerful, and coding the
    front end in REXX has meant that I can add features quickly and easily.

    The front-end script has got up to about 11k lines at this point, which
    is a bit big for a REXX program, and I'm now finding that adding
    functions has a tendency to break things. (Classic REXX isn't the most
    structured language in the world.) I've spent some time chasing stupid
    stuff like inconsistent EXPOSE lists, when adding a feature means I need
    access to a global stem down in some function that didn't previously
    need it.

    TRACE ?I isn't the friendliest thing in the world for this--I can only
    check things that the interpreter is actually evaluating at the time,
    which makes it more like printf() than like Visual Studio or even ddd.

    So I need a REXX debugger. I found S/REXX on the Web, but it doesn't
    look that compelling--it looks like a mildly-glorified TRACE ?.

    Is there a better one?

    Thanks,

    Phil Hobbs

  2. Default Re: REXX debugger

    On Thu, 20 Sep 2007 15:14:14 -0400, Phil Hobbs
    <pcdh@SpamMeSenseless.pergamos.net> wrote:
    <46F2C686.2000309@SpamMeSenseless.pergamos.net>


    >So I need a REXX debugger. I found S/REXX on the Web, but it doesn't
    >look that compelling--it looks like a mildly-glorified TRACE ?.
    >
    >Is there a better one?


    Some years back when I started writing fairly elaborate REXX routines (1988 or
    so), I settled on a protocol in which I pass operational parms left of a
    double-open-paren ("((") and diagnostic parms to the right.

    The diagnostics are all parsed out in a subroutine which is called VERY early in
    the process (i.e.: FIRST). One of the parms it recognizes is "TRAPOUT". When
    the parsing routine finds token "TRAPOUT" it does this:

    if SWITCH("TRAPOUT") then do
    "TRAPOUT" exec_name parms "(( TRACE R" info
    exit
    end

    That is, it fires up an external routine called TRAPOUT:
    --------------------------------------------------------------------------
    /* Rexx */ /* This is REXX EXEC "TRAPOUT" to trap line output */
    address TSO
    rc = trace("O")
    "EXECUTIL TE"
    Parse arg TSOCMD /* A TSO Command will be the input parm */
    rc = Outtrap("OUT.") /* Turn on outtrap, to rexx stem OUT. */
    (TSOCMD) "(( TRACE R" /* Do the command */
    rc = Outtrap("OFF")

    If OUT.0 > 0 Then Do /* If any output, write to the file */
    dsdate = Right(date("S"),6) /* 950118 maybe */
    dstime = time()
    parse var dstime th ":" tm ":" ts .
    dstime = Right(th,2,0)Right(tm,2,0)Right(ts,2,0)
    dsn = "@@TRAP.D"dsdate".T"dstime".LIST"
    X = Msg("OFF");"DEL" dsn ;X= Msg("ON")
    "ALLOC FI(TRAPOUT) DA("dsn") NEW CATALOG REU SP(5,5) CYL ",
    "RECFM(V B) LRECL(255) BLKSIZE(0)"
    "EXECIO" out.0 "DISKW TRAPOUT (STEM OUT. FINIS"
    "FREE FI(TRAPOUT)"
    end
    --------------------------------------------------------------------------

    TRAPOUT sets up a SYSOUTTRAP and re-invokes the original routine with all
    parameters except "TRAPOUT" but with "TRACE R". When the routine completes, the
    contents of the trap are spilled onto a real dataset.

    Notice that the dataset is allocated "SPACE(5,5) CYL". There have been more
    instances than I'm comfortable acknowledging where this was barely enough. This
    solves a problem where the program fails at output-line 112,387 because of an
    error at output-line 2,559. There is no other way you would ever find that.

    (I just this instant noticed an error here: the code to invoke TRAPOUT specifies
    "TRACE R" and TRAPOUT itself does it again. One of these is redundant (the
    specification in TRAPOUT).)

    You can see several examples of code which implements this protocol at
    http://web.tampabay.rr.com/mvsrexx/REXX/. Good luck.


    (change Arabic number to Roman numeral to email)

  3. Default Re: REXX debugger

    Phil Hobbs <pcdh@SpamMeSenseless.pergamos.net> wrote in
    news:46F2C686.2000309@SpamMeSenseless.pergamos.net:
    >
    > The front-end script has got up to about 11k lines at this point, which
    > is a bit big for a REXX program, and I'm now finding that adding
    > functions has a tendency to break things. (Classic REXX isn't the most
    > structured language in the world.) I've spent some time chasing stupid
    > stuff like inconsistent EXPOSE lists, when adding a feature means I

    need
    > access to a global stem down in some function that didn't previously
    > need it.
    >

    I support an app that consists of hundreds of classic REXX programs, some
    >13k lines. To avoid the problems you describe with EXPOSE lists we

    adopted a few simple standards.

    The start of each program sets a variable "globals" to the variables or
    stems to be exposed i.e.

    globals = '$. cust. foo.'

    Then each subroutine has "procedure expose (globals)"

    Any variable that is to be global starts wth a $. -- $.0fileName,
    $.0returnCode etc.

    We use lots of stems to sorta kinda simulate objects. For example all
    the information about a customer is in the "cust." stem -- cust.0name
    cust.0address etc. By prefixing the second token with a 0 we don't have
    to worry about "cust.name" getting stomped on if someone decides to use
    "name" as alocal variable.

    If you find a good debugger let us know.

  4. Default Re: REXX debugger

    Phil Hobbs wrote:
    > The front-end script has got up to about 11k lines at this point, which
    > is a bit big for a REXX program, and I'm now finding that adding
    > functions has a tendency to break things. (Classic REXX isn't the most
    > structured language in the world.) I've spent some time chasing stupid
    > stuff like inconsistent EXPOSE lists, when adding a feature means I need
    > access to a global stem down in some function that didn't previously
    > need it.


    Well, one suggestion (which won't help you with your debugging) is to
    put all truly global variables into a common stem and ensure that you
    expose that everywhere you use "procedure".

    My chosen common stem is "C." and the tails always start with a "0" (to
    ensure that they are immutably constant). So the debug flag, c.0debug is
    available throughout my code.

    I cannot type the sequence "procedure expose" without my fingers wanting
    to add "c."

    Many of my routines start with:

    If symbol(C.0debug) = 'VAR'
    then call exit "C.0debug is undefined at line" sigl

    This requires that I expose "sigl" as well, if this is in a routine
    which starts with "procedure"

    Alternatively, if you want global variables without exposing them, you
    could use environment variables, but I normally restrict this to
    desperate measures, for performance reasons.

    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk

  5. Default Re: REXX debugger

    On Sep 21, 12:29 am, Steve Swift <Steve.J.Sw...@gmail.com> wrote:
    > Phil Hobbs wrote:
    > > The front-end script has got up to about 11k lines at this point, which
    > > is a bit big for a REXX program, and I'm now finding that adding
    > > functions has a tendency to break things. (Classic REXX isn't the most
    > > structured language in the world.) I've spent some time chasing stupid
    > > stuff like inconsistent EXPOSE lists, when adding a feature means I need
    > > access to a global stem down in some function that didn't previously
    > > need it.

    >
    > Well, one suggestion (which won't help you with your debugging) is to
    > put all truly global variables into a common stem and ensure that you
    > expose that everywhere you use "procedure".
    >
    > My chosen common stem is "C." and the tails always start with a "0" (to
    > ensure that they are immutably constant). So the debug flag, c.0debug is
    > available throughout my code.
    >
    > I cannot type the sequence "procedure expose" without my fingers wanting
    > to add "c."
    >
    > Many of my routines start with:
    >
    > If symbol(C.0debug) = 'VAR'
    > then call exit "C.0debug is undefined at line" sigl
    >
    > This requires that I expose "sigl" as well, if this is in a routine
    > which starts with "procedure"
    >
    > Alternatively, if you want global variables without exposing them, you
    > could use environment variables, but I normally restrict this to
    > desperate measures, for performance reasons.
    >
    > --
    > Steve Swifthttp://www.swiftys.org.uk/swifty.htmlhttp://www.ringers.org.uk


    Funny, in 20 years of coding nothing but Rexx, I have never had the
    remotest desire to put a PROCEDURE statement on any of my called
    routines.

    Mickey


  6. Default Re: REXX debugger

    Steve Swift wrote:
    > Phil Hobbs wrote:
    >> The front-end script has got up to about 11k lines at this point,
    >> which is a bit big for a REXX program, and I'm now finding that adding
    >> functions has a tendency to break things. (Classic REXX isn't the
    >> most structured language in the world.) I've spent some time chasing
    >> stupid stuff like inconsistent EXPOSE lists, when adding a feature
    >> means I need access to a global stem down in some function that didn't
    >> previously need it.

    >
    > Well, one suggestion (which won't help you with your debugging) is to
    > put all truly global variables into a common stem and ensure that you
    > expose that everywhere you use "procedure".
    >
    > My chosen common stem is "C." and the tails always start with a "0" (to
    > ensure that they are immutably constant). So the debug flag, c.0debug is
    > available throughout my code.
    >
    > I cannot type the sequence "procedure expose" without my fingers wanting
    > to add "c."
    >
    > Many of my routines start with:
    >
    > If symbol(C.0debug) = 'VAR'
    > then call exit "C.0debug is undefined at line" sigl
    >
    > This requires that I expose "sigl" as well, if this is in a routine
    > which starts with "procedure"
    >
    > Alternatively, if you want global variables without exposing them, you
    > could use environment variables, but I normally restrict this to
    > desperate measures, for performance reasons.
    >


    My life also improved a good deal when I found out about PROCEDURE
    EXPOSE (globallist). I use c-like ASSERT and ABORT functions (complete
    with checking ndebug). Making abort() optionally divide by zero causes
    a traceback so I can at least figure out the call stack post-mortem,
    which is often a huge help--but nowhere near what even a poor debugger
    would provide.

    Cheers,

    Phil hobbs

    ---------------------------------------------

    abort:
    AbortErrcode=arg(1)
    AbortErrtext= arg(2)

    do i=3 to 100
    if arg(i) = '' then leave
    AbortErrtext = AbortErrtext arg(i)
    end /* do */

    if datatype(AbortErrcode) <> 'NUM' then do
    AbortErrtext = AbortErrcode AbortErrtext
    AbortErrcode = -9999
    end /* if */

    call lineout 'stderr', '('AbortErrcode')' AbortErrtext
    call lineout 'stderr'

    if global.7debug > 0 then traceback=1/0; /* cause trace-back */
    exit(AbortErrcode);
    return

    assert: /* uses the caller's variable names--can also supply the value
    as a second argument */
    /* Usage: call assert "x < y"
    * call assert "X must be less than Y", x < y
    * call assert x" is greater than "y, x < y
    */

    if ndebug=1 then return 0;
    _assrtexpr = strip(arg(1),'b',' ');
    _assrtval = arg(2);

    if datatype(_assrtval) <> 'NUM' then do
    interpret('_assrtval = ('_assrtexpr')')
    if datatype(_assrtval) <> "NUM" then
    call abort -1, "Assert error: non-numeric expression
    "_assrtexpr"'";
    end /* if */

    if 0 = _assrtval then do
    if ErText <> 'ERTEXT' then say ErText;
    call abort -2, "Assertion failure: '"_assrtexpr"'";
    end
    return '';


  7. Default Re: REXX debugger

    Mickey wrote:
    > On Sep 21, 12:29 am, Steve Swift <Steve.J.Sw...@gmail.com> wrote:
    >> Phil Hobbs wrote:
    >>> The front-end script has got up to about 11k lines at this point, which
    >>> is a bit big for a REXX program, and I'm now finding that adding
    >>> functions has a tendency to break things. (Classic REXX isn't the most
    >>> structured language in the world.) I've spent some time chasing stupid
    >>> stuff like inconsistent EXPOSE lists, when adding a feature means I need
    >>> access to a global stem down in some function that didn't previously
    >>> need it.

    >> Well, one suggestion (which won't help you with your debugging) is to
    >> put all truly global variables into a common stem and ensure that you
    >> expose that everywhere you use "procedure".
    >>
    >> My chosen common stem is "C." and the tails always start with a "0" (to
    >> ensure that they are immutably constant). So the debug flag, c.0debug is
    >> available throughout my code.
    >>
    >> I cannot type the sequence "procedure expose" without my fingers wanting
    >> to add "c."
    >>
    >> Many of my routines start with:
    >>
    >> If symbol(C.0debug) = 'VAR'
    >> then call exit "C.0debug is undefined at line" sigl
    >>
    >> This requires that I expose "sigl" as well, if this is in a routine
    >> which starts with "procedure"
    >>
    >> Alternatively, if you want global variables without exposing them, you
    >> could use environment variables, but I normally restrict this to
    >> desperate measures, for performance reasons.
    >>
    >> --
    >> Steve Swifthttp://www.swiftys.org.uk/swifty.htmlhttp://www.ringers.org.uk

    >
    > Funny, in 20 years of coding nothing but Rexx, I have never had the
    > remotest desire to put a PROCEDURE statement on any of my called
    > routines.
    >
    > Mickey
    >


    Well, either you write simple programs exclusively, or you have an
    amazing head for details. Calling a function from inside a loop and
    having a 'local' variable clobber your loop counter gets old after awhile.

    There are a couple of places in my simulator front end where I really
    really need to execute in the caller's context--that's very typical when
    you're using INTERPRET, for instance, or when you want to be able to
    pull a file into a stem in Classic REXX. I write the routine as usual,
    then use search-and-replace to add an eyecatcher to all the variable
    names, to avoid clobbering anyone. As they said in 'Stalag 17', "crude
    but effective."

    Cheers,

    Phil Hobbs

    (*) Just so we don't get into the INTERPRET wars again, I use it as a
    macro processor.

  8. Default Re: REXX debugger

    > Well, either you write simple programs exclusively, or you have an
    > amazing head for details. Calling a function from inside a loop and
    > having a 'local' variable clobber your loop counter gets old after awhile.


    Having been raised on FORTRAN I find it impossible to use anything other
    than I,J,K,L,M or N as the counter in do loops. I have procedures nested
    at least 8 levels deep calling other procedures from inside loops, so
    I'd rapidly run out of counters if I didn't use "procedure".

    I'll admit that it's probably faster without the "procedure", if you can
    manage it. I wouldn't last 10 minutes.

    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk

  9. Default Re: REXX debugger

    In Message-ID:<46f565c3@news.greennet.net>,
    Steve Swift <Steve.J.Swift@gmail.com> wrote:

    >Having been raised on FORTRAN I find it impossible to use anything other
    >than I,J,K,L,M or N as the counter in do loops.


    About the same here, though I've been known to go to
    2-character names, when forced (i1 or ii).

    "God is real, unless declared integer."

    --
    Arthur T. - ar23hur "at" intergate "dot" com
    Looking for a z/OS (IBM mainframe) systems programmer position

  10. Default Re: REXX debugger

    On Sep 21, 11:43 am, Phil Hobbs
    <pcdhSpamMeSensel...@electrooptical.net> wrote:
    > Mickey wrote:
    > > On Sep 21, 12:29 am, Steve Swift <Steve.J.Sw...@gmail.com> wrote:
    > >> Phil Hobbs wrote:
    > >>> The front-end script has got up to about 11k lines at this point, which
    > >>> is a bit big for a REXX program, and I'm now finding that adding
    > >>> functions has a tendency to break things. (Classic REXX isn't the most
    > >>> structured language in the world.) I've spent some time chasing stupid
    > >>> stuff like inconsistent EXPOSE lists, when adding a feature means I need
    > >>> access to a global stem down in some function that didn't previously
    > >>> need it.
    > >> Well, one suggestion (which won't help you with your debugging) is to
    > >> put all truly global variables into a common stem and ensure that you
    > >> expose that everywhere you use "procedure".

    >
    > >> My chosen common stem is "C." and the tails always start with a "0" (to
    > >> ensure that they are immutably constant). So the debug flag, c.0debug is
    > >> available throughout my code.

    >
    > >> I cannot type the sequence "procedure expose" without my fingers wanting
    > >> to add "c."

    >
    > >> Many of my routines start with:

    >
    > >> If symbol(C.0debug) = 'VAR'
    > >> then call exit "C.0debug is undefined at line" sigl

    >
    > >> This requires that I expose "sigl" as well, if this is in a routine
    > >> which starts with "procedure"

    >
    > >> Alternatively, if you want global variables without exposing them, you
    > >> could use environment variables, but I normally restrict this to
    > >> desperate measures, for performance reasons.

    >
    > >> --
    > >> Steve Swifthttp://www.swiftys.org.uk/swifty.htmlhttp://www.ringers.org.uk

    >
    > > Funny, in 20 years of coding nothing but Rexx, I have never had the
    > > remotest desire to put a PROCEDURE statement on any of my called
    > > routines.

    >
    > > Mickey

    >
    > Well, either you write simple programs exclusively, or you have an
    > amazing head for details. Calling a function from inside a loop > and having a 'local' variable clobber your loop counter gets old > after awhile.


    In this case, the latter. I have some Rexx programs that are 10k lines
    (don't ask, the details are brutal), but I pay close attention to loop
    counters and indecies for input and output files.

    Mickey


+ Reply to Thread
Page 1 of 3 1 2 3 LastLast

Similar Threads

  1. Replies: 7
    Last Post: 02-17-2007, 10:13 PM
  2. Linux, Cannot open REXX message catalog rexx.cat
    By Application Development in forum REXX
    Replies: 0
    Last Post: 08-15-2006, 07:46 AM
  3. REXX pgm calling another REXX pgm not on the PATH
    By Application Development in forum REXX
    Replies: 7
    Last Post: 05-16-2006, 02:08 AM
  4. New Rexx Book: Rexx Programmer's Reference
    By Application Development in forum REXX
    Replies: 30
    Last Post: 06-22-2005, 10:40 PM
  5. Running Object Rexx rexx.exe as a NT Service
    By Application Development in forum REXX
    Replies: 3
    Last Post: 01-14-2005, 05:01 AM