One item that has eluded me in my continuing quest to dive deeply into z Systems architecture is finding a native (IBM-supplied) assembler debugger/disassembler** on the platform that is fully functional, user-friendly and versatile.

Quickly I gave up on user-friendly and versatile and settled on trying to find one that was fully functional; simply stated – can execute and sustain integrity through any command in the POP manual. Of the 4 debuggers on the system, or as part of an add-on package, all have major out-of-the box ‘features’ that prevent them from being a worthwhile tool to anyone who has used a modern debugger (Like Immunity, Olly, or even GNU’s gdb).*

For this platform, my criteria for fully functional was this:

Be able to debug programs which are link-edited APF-authorized and live in APF authorized libraries. Debug programs that switch into and out of supervisor state, and also switch PSW key mask values. Allow execution of commands that switch address space control (ASC) modes and manipulate storage in any of the 3 modes. Do the rest of the actions a basic debugger would do: set breakpoints, single step, watch variables / registers, examine and change memory, and so on.

The first 3 are functions unique to the z/Architecture platform, and I would expect at least the 3 z/OS based debuggers to handle (and possibly the one OMVS/USS based one also). None do. At least out of the box. A quick list of the debuggers tried, and their limitations is at the end of this post.

I say “out of the box” because I have had success in modifying one of the tools (HLASM Toolkit Debugger, aka IDF) to do the items listed above with any major restrictions (that I’ve found thus far). For the TL;DR crowd, the modifications which allowed this to happen were this: (Disclaimer: I’m assuming anyone doing this has the authority, permission and understands the potential security repercussions of doing so. If not, please stop and find someone who does).

APF authorize a copy of, or the library from which, the ASMIDF tool runs. Link edit the ASMIDF load module AC=1 Add ASMIDF to the TSO authorized commands / programs list ( I didn’t test to see if one or the other was sufficient, just did both ). Test with a simple program that uses some privileged commands and Macros.

For the rest of you who, like me, needed to understand a bit more on what each of these steps entail, read on. Also, in full disclosure, I came across this idea via a Google search on the topic which yielded 2 hits of people who said they’d tried and mostly succeed at this method. Though, in true MVS form, neither explained how to do so. I’ll break each step down, with some examples here.

APF authorize a copy of the IDF library.

I used a copy of the library, just to be safe, then dynamically authorized it and added it to my link list concatenation. Here’s a simple JCL to copy the library (you’ll have to fill in your own HLQ’s and library names as appropriate):

//MYJOB JOB (GUY),'iebcopy ds', // NOTIFY=&SYSUID, // MSGCLASS=H, // MSGLEVEL=(1,1) //* //* IEBCOPY members from one DS to another //* //STEP1 EXEC PGM=IEBCOPY //SYSUT1 DD DSN=HLQ.ASMLIB.SRC,DISP=SHR /* INPUT DS */ //SYSUT2 DD DSN=HLQ.ASMLIB.NEW,DISP=(NEW,CATLG), /* OUTPUT DS */ // SPACE=(TRK,(80,50,20)),UNIT=SYSALLDA, // BLKSIZE=6144,VOL=SER=TEMP1, // RECFM=U,DSNTYPE=PDS,LRECL=0 //SYSPRINT DD SYSOUT=A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 / / MYJOB JOB ( GUY ) , 'iebcopy ds' , / / NOTIFY =& amp ;SYSUID, / / MSGCLASS = H , / / MSGLEVEL = ( 1 , 1 ) / / * / / * IEBCOPY members from one DS to another / / * / / STEP 1 EXEC PGM = IEBCOPY / / SYSUT 1 DD DSN = HLQ . ASMLIB . SRC , DISP = SHR / * INPUT DS * / / / SYSUT 2 DD DSN = HLQ . ASMLIB . NEW , DISP = ( NEW , CATLG ) , / * OUTPUT DS * / / / SPACE = ( TRK , ( 80 , 50 , 20 ) ) , UNIT = SYSALLDA , / / BLKSIZE = 6144 , VOL = SER = TEMP 1 , / / RECFM = U , DSNTYPE = PDS , LRECL = 0 / / SYSPRINT DD SYSOUT = A

The following commands (issued from a console or SDSF) will apf authorize the library.

SETPROG APF,ADD,DSNAME=HLQ.ASMLIB.NEW 1 SETPROG APF , ADD , DSNAME = HLQ . ASMLIB . NEW

Link edit the copy of ASMIDF AC=1

This apf authorizes the load module itself. (You can verify this by looking at the file, once this has run in ISPF. You should see 01 in the AC column.

//MYJOB JOB (GUY),'setcode', // NOTIFY=&SYSUID, // MSGCLASS=H, // MSGLEVEL=(1,1) //* //* //* //SETCODE EXEC PGM=HEWL //SYSPRINT DD SYSOUT=A //SYSUT1 DD UNIT=SYSALLDA,SPACE=(TRK,(10,5)) //SYSLMOD DD DSN=HLQ,ASMLIB.NEW,DISP=SHR //SYSLIN DD DSN=HLQ.ASMLIB.NEW(ASMIDF),DISP=(SHR,PASS), // UNIT=SYSDA // DD * SETCODE AC(1) ENTRY ASMMAIN NAME ASMIDF(R) /* //* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 / / MYJOB JOB ( GUY ) , 'setcode' , / / NOTIFY =& SYSUID , / / MSGCLASS = H , / / MSGLEVEL = ( 1 , 1 ) / / * / / * / / * / / SETCODE EXEC PGM = HEWL / / SYSPRINT DD SYSOUT = A / / SYSUT 1 DD UNIT = SYSALLDA , SPACE = ( TRK , ( 10 , 5 ) ) / / SYSLMOD DD DSN = HLQ , ASMLIB . NEW , DISP = SHR / / SYSLIN DD DSN = HLQ . ASMLIB . NEW ( ASMIDF ) , DISP = ( SHR , PASS ) , / / UNIT = SYSDA / / DD * SETCODE AC ( 1 ) ENTRY ASMMAIN NAME ASMIDF ( R ) / * / / *

Add the new library to your link list, remove the old one

This ensures you won’t run into issues using the old one (assuming you log out, back in before trying ASMIDF when you’re done with this procedure).

D PROG,LNKLST #get old lnklst name e.g. LNKLST00 SETPROG LNKLST,DEFINE,NAME=TESTLL,COPYFROM=LNKLST00 SETPROG LNKLST,DELETE,NAME=TESTLL,DSNAME=HLQ.ASMLIB.SRC SETPROG LNKLST,ADD,NAME=TESTLL,DSNAME=HLQ.ASMLIB.NEW,ATTOP SETPROG LNKLST,ACTIVATE,NAME=TESTLL 1 2 3 4 5 6 7 8 9 D PROG , LNKLST # get old lnklst name e . g . LNKLST 00 SETPROG LNKLST , DEFINE , NAME = TESTLL , COPYFROM = LNKLST 00 SETPROG LNKLST , DELETE , NAME = TESTLL , DSNAME = HLQ . ASMLIB . SRC SETPROG LNKLST , ADD , NAME = TESTLL , DSNAME = HLQ . ASMLIB . NEW , ATTOP SETPROG LNKLST , ACTIVATE , NAME = TESTLL

Add ASMIDF to the TSO/E authorized cmd and pgm lists.

D IKJTSO # capture the name of the parmlib member e.g. IKJTSO55 [ need to make a copy of that member in the parmlib, IKJTSO99 ] [ edit the IKJTSO99 member to add ASMIDF to the following sections ] AUTHCMD NAMES( + ASMIDF + <-add this line AD ADDSD + ----------------------------- AUTHPGM NAMES( + ASMIDF + <-and this one ICHUT100 + [ then back to the console to set the new member active ] SET IKJTSO=99 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 D IKJTSO # capture the name of the parmlib member e . g . IKJTSO 55 [ need to make a copy of that member in the parmlib , IKJTSO 99 ] [ edit the IKJTSO 99 member to add ASMIDF to the following sections ] AUTHCMD NAMES ( + ASMIDF + < - add this line AD ADDSD + -- -- -- -- -- -- -- -- -- -- -- -- -- -- - AUTHPGM NAMES ( + ASMIDF + < - and this one ICHUT100 + [ then back to the console to set the new member active ] SET IKJTSO = 99

All of the steps, except the initial copy/link edit, will not survive an IPL. To do that, you need to edit your PROGXX and possibly IEASYSXX parmlib members and add / remove the corresponding libraries accordingly.

The tools and their issues:

OMVS/USS dbx Despite making all of the RACF profile and authorization changes suggested in the manuals, and trying a multitude of users / programs and methods, I could not get dbx to debug an apf authorized program. The manual quote is below: .... enables you to debug APF-authorized programs, using ptrace 1 . . . . enables you to debug APF - authorized programs , using ptrace

Debug Tool for z/OS The most festively-colored of the bunch, and able to debug apf authorized programs, this tool chokes on any of the linkage stack commands (BAKR, for example) and anything that uses the AR ASC mode. From the manual: Debugging of programs that use Access Register mode is not supported. You cannot debug programs that do not use standard linkage conventions for registers 13, 14, and 15 or that use the Linkage Stack. 1 2 3 Debugging of programs that use Access Register mode is not supported . You cannot debug programs that do not use standard linkage conventions for registers 13 , 14 , and 15 or that use the Linkage Stack .

TSO/E test and testauth commands The grandaddy of them all has a great deal of functionality, will execute authorized programs and commands, but doesn’t fit the rest of the bill. Frankly, even if it did, it would be a pretty tedious task to do any significant quantity of debugging in this tool. But hey, who wouldn’t want to live in this all day long:

Before the cantankerous crew chastises me about how much code they ran through back in the day using only TSO/E test and a slide rule, let me just say this:I love text based interfaces. I generally prefer the likes of gdb/windbg to one of the gui based programs for many items (not all, but many) because it’s faster, scriptable and generally more powerful in many occasions. However, there is value in much of the progress that’s been made in this area – going backward for nostalgia’s sake is one thing, but eschewing technological progress for it’s own sake is quite another. ASMIDF (so far so good)

Hope you enjoyed the post – and, if you’re still reading this and going to SHARE in the spring, I’ll see you there!

Footnotes:

** (Note for the rest of this article I’m going to just use the term debug to mean debugging and disassembly – I realize there are significant differences in these terms, but for my purposes I need a tool which does both.

* Notably absent is Hexray’s Ida Pro, considered the gold-standard by many, this is so richly-featured to really be in a league of it’s own.