MVS TOOLS AND TRICKS OF THE TRADE January 1998 Sam Golob MVS Systems Programmer P.O. Box 906 Tallman, New York 10982 Sam Golob is a Senior Systems Programmer. LOOKING AT VIRTUAL STORAGE Many of us would write much more code if we could only see what we were writing about. I still remember when I was an application programmer. If I ever had to write a program to manipulate a file, I always had to get a sample production file, and copy it as a test file. Then I'd look at it very carefully before attempting to write my code. You have to see the data you're programming about. I also remember much later, as a systems programmer, when I was enhancing the TAPEMAP program (from File 299 of the CBT MVS Tape). TAPEMAP is very careful to "feel" the data at the beginning of each tape file, in order to classify it as IEBCOPY format, IEBUPDTE, SMPPTFIN, etc. Therefore, I needed the TAPESCAN program (from File 102 of the CBT tape) or the DITTO tape functions, to give me a byte-by-byte detailed description of all the tape files to be studied, in hex. I had to look, in order to be able to program. Now here's the 64 dollar question: "When you're a systems programmer writing code that accesses system control blocks in virtual storage, how can you get a good look at the data you're writing about?" Remember that you have to look at actual virtual storage which is running in your address space, or in another address space, and it helps, if you can follow control block chains. There are a few vendor tools to do this, such as the XDC Debugger from Cole Software, and there's TSO TEST, but there's also a free tool that can be had and used, by anybody. This is the extremely clever LOOK program from File 264 of the CBT MVS Utilities Tape. LOOK was enhanced by Guy Albertelli from the original program, which was once part of a free software product called DCMS. This LOOK program or any similar product, is an absolute must to use, if you're writing system level code, and you need to see the data in detail. The CBT MVS Utilities Tape, if you don't already know, is an independently produced tape which is distributed by several sources, including NaSPA. The tape may be freely copied, and it is of immense value to MVS Systems Programmers. When you need to do a job, and you don't know how to do it, the CBT Tape is one of the first places to search, to find out if someone else has done a similar job already. Most of the software on the CBT Tape is in source form, and you can study it and modify it to your heart's content. So you can get your job done, and you can learn to code in assembler or PL/I, or whatever language the software is written in, better than you could before. Now we'll begin to see how the LOOK program can show us in-storage data, and format it automatically as a system control block. Then we'll navigate through storage, from control block to control block, from pointer to pointer, and from there to the data. My friend and teacher Jeff Broido told me early in my training, that whenever he wrote system code to access control blocks, he would always see what he was doing by using the LOOK program. WHAT KIND OF PROGRAM IS "LOOK"? LOOK is a TSO command, which is designed to run interactively, in full screen mode, under TSO. LOOK will show you chunks of virtual storage in your own address space, in HEX and EBCDIC. This gives you access to common storage as well. If LOOK is running authorized, LOOK is capable of showing similar private storage in any other address space. It does this by issuing an SRB to go cross memory to retrieve the block of storage from the other address space. A user of LOOK goes from one full screen of data to another. Two pfkeys enable the user to go back to previous screens, or to go forward. From any screen of data, you can explore new storage as you like. Once you learn the subcommands of LOOK, you'll come to appreciate its great flexibility. Today we'll see how LOOK works, by actually doing something. A simple program I once wrote, a TSO command to display your own userid, finds the userid by following pointers in control blocks, starting from the CVT (Commuication Vector Table), which is the "backbone" of pointers to most locations on an MVS or OS/390 system. Figure 1 shows the actual simple code, and Figures 2 through 6 show LOOK screens which illustrate the storage at each control block location, as we follow the chain to the location of the PSCB, and the data we want. Using LOOK, you can see what you're programming. You're not working in the dark. LOOK has quite a few useful commands. You can enter a virtual address, and LOOK will take you there, if the address is accessible. LOOK always has a current address pointer. Its initial value is 00000000, or low storage. This is formatted as PSA, or Prefixed Save Area. Indirect addressing is done with an I or a J. I, which is a carryover from the 24-bit only days, does indirect addressing in 24-bit mode. J does indirect addressing in 31-bit mode. Indirect addressing means the following: If a fullword in virtual storage contains an address of somewhere else in virtual storage, then a J command, on the current fullword, will take you to the address that's in that fullword. This corresponds to a LOAD instruction in assembler language. The J instruction therefore helps us follow control block chains. The code in the assembler program of Figure 1, has a sequence of five LOAD instructions. The corresponding commands to LOOK, illustrated by Figures 2 thru 6, are a sequence of five J instructions. Figure 7 shows the LOOK help screen. LOOK doesn't have an enormous number of commands, but what it does have, allows for great flexibility to track locations in virtual machine storage. One other noteworthy aspect of LOOK, is its ability to recognize and format system control blocks, and to run from one control block to another, through indirect LINKs. LOOK contains very clever code which allows you to format any control block fields, according to their macro definitions. In other words, LOOK can format fields in the CVT through an assembly of the CVT macro. The TCB can be formatted by invoking an assembly of the IKJTCB macro. The ASCB is formatted by assembling the IHAASCB macro, and so forth. By coding a few lines in the CBMACS source member, any control block that is described by a mapping macro, can be formatted to the LOOK program. If a control block is formatted on a LOOK screen, you can get to any address in a formatted field, by using a LINK or L command. For example, look at Figure 2, which is a formatted mapping of the CVT. If you want to display the location of the TCBP field from the CVT, you can enter the command LTCBP (or Link to TCBP), and you'll display storage starting at the location specified in the address, which is 00000218. So, starting from the CVT, you can get to the TCBP field by either entering J+0, or LTCBP, or 00000218 as commands. They will all yield the same result. Space is short this month, because of all the illustrations, but since a picture is worth a thousand words, there should be a lot of content in what we've said today. Whether you're writing code, or checking up on how your system is working, or diagnosing a system problem, or simply exploring, it pays to be able to see the storage that's in the system. Good luck, and good LOOKing. See you next month. * * * * * * * * * * * * * * * * * * * * * * * Figure 1. This is a simple TSO command called MYID, which finds the userid of the invoker, and displays it on the tube. This command gets the userid from the PSCBUSER field of the TSO Protected Step Control Block (PSCB). This field is obtained by running a control block chain starting from the CVT, as illustrated by the code. Then we're going to use the LOOK program to actually see the storage at each stage. * M Y I D P R O G R A M - A T S O C O M M A N D * * TSO COMMAND PROCESSOR TO DISPLAY THE USERID OF THE INVOKER. * * ------ REGISTER EQUATES ELIMINATED FOR BREVITY ------------ * MYID CSECT STM R14,R12,12(R13) SAVE CALLER'S REGISTERS R14 THRU R12 LR R12,R15 LOAD ENTRY POINT INTO BASE REGISTER USING MYID,R12 TELL THE ASSEMBLER, R12 IS THE BASE LR R15,R13 SAVE CALLER'S SAVEAREA ADDRESS LA R13,SAVE POINT R13 TO OUR SAVEAREA ADDRESS ST R15,SAVE+4 STORE HIS SAVEAREA INTO MINE + 4 ST R13,8(,R15) STORE MINE INTO HIS SAVEAREA + 8 RUNCHAIN L R3,16 POINT TO CVT. ADDR IS IN LOW STORAGE L R3,0(,R3) POINT TO TCB/ASCB WORDS, "0" OFF CVT L R3,4(,R3) POINT TO TCB, "4" OFF TCB/ASCB WORDS L R3,X'B4'(,R3) POINT TO JSCB. X'B4' OFF CURRENT TCB L R3,X'108'(,R3) POINT TO PSCB. X'108' OFF THE JSCB MVC MSGLINE+13(7),0(R3) MOVE USERID IN FROM 0 OFF THE PSCB TPUT MSGLINE,L'MSGLINE DISPLAY THE WHOLE MESSAGE ON THE TUBE RETURN DS 0H L R13,SAVE+4 RELOAD CALLER'S SAVEAREA POINTER LM R14,R12,12(R13) RELOAD THE CALLER'S REGISTERS BR R14 RETURN TO CALLER SAVE DC 18F'0' DEFINE MY SAVEAREA - 18 FULLWORDS MSGLINE DC CL20'MY USERID IS ' DEFINE LINE FOR MESSAGE END * * * * * * * * * * * * * * * * * * * * * * * Figure 2. This is the LOOK screen, with the first page of the CVT, formatted out. You get to the CVT from the pointer at virtual location X'10' or Decimal 16. In LOOK parlance, the command is J10. You see that LOOK uses the hex value. LOOK COMMAND - DISPLAY VIRTUAL MEMORY DISPLAY ASID= 0029 ENTER CMD - LAST CMD - J10 00FDA068 CVT TCBP 00000218 0EF00 00FE5E90 LINK 00FD511C AUSCB 00FD7D48 BUF 00000000 XAPG 00FF80C4 0VL00 00FF2ECE PCNVT 00FFC114 PRLTV 00FFBF44 LLCB 0155ECD8 LLTRM 81162940 XTLER 00FEAEF8 SYSAD 00F4A080 BTERM 00FF5030 DATE 0097334F MSLT 00FD5908 ZDTAB 00F41000 XITP 00FFA5E8 0EF01 00FE60B8 VSS 0000 VPSM 0000 SVDCB 00FD5124 TPC 00FD3308 RS05C 0000 ICPID 0000 RS060 40C3E5E3 CUCB 00FD5AA0 QTE00 00FDE90A QTD00 00FDE92A STB 00F4C580 DCB 9B DCBA FD7E18 SV76M 00000000 IXAVL 00FE1400 NUCB 00000000 FBOSV 8150A278 0DS 00FEB9B8 ECVT 0155EE18 DAIRX 82F11000 MSER 00FD5908 0PT01 00FEEA18 TVT 00CA6260 SV76C 00000000 MZ00 7F 1EF00 00000000 QOCR 00000000 QMWR 00FD7D10 SNCTR 0000 OPTA A3 OPTB 20 QCDSR 00FE66E0 QLPAQ 00FD5158 ENFCT 00FDA650 SMCA 80FC2B20 ABEND 00FD3210 USER 00000000 MDLDS 00000000 TSCE 00000000 PATCH 00FD4978 RMS 0142E190 SPDME 01F93B6C 0SCR1 00FFB598 GTFST 00 GTFA FCEC20 TCMFG 00 AQAVB 000000 RS0F4 00000000 1= HELP 2= 3= END 4= 5= REPEAT 6= 7= BACKWARD 8= FORWARD 9= HIST BWD 10= HIST FWD 11= 12= * * * * * * * * * * * * * * * * * * * * * * * Figure 3. This is storage (unformatted) at the location of the TCB pointers for your address space. If LOOK recognizes a control block and formats it, you can turn off the formatting with the command: ONULL. If you want to purposely format some storage as if it were a CVT, you would use the command: OCVT . You get the idea. LOOK COMMAND - DISPLAY VIRTUAL MEMORY DISPLAY ASID= 0029 ENTER CMD - LAST CMD - J+0 00000218 >009B81F8 009B81F8 00FD3600 00FB6D00 *>...8...8......_.* 00000228 00000000 00000000 00000000 00000000 *................* 00000238 00000000 00000078 00000000 00000000 *................* 00000248 00000000 7F748950 040C0000 00DF1DF2 *...."..&.......2* 00000258 040C0000 8003986C AD000950 AD000950 *.......%...&...&* 00000268 AD040950 AD000950 AD040950 00000000 *...&...&...&....* 00000278 00000704 00000000 00FD13E8 00000000 *...........Y....* 00000288 00FD13F0 00000000 00000000 00000000 *...0............* 00000298 00000000 00000000 00000000 00000000 *................* 000002A8 00FD13F8 00000000 00FD1430 00000000 *...8............* 000002B8 00000000 00000000 00000000 00FD1440 *............... * 000002C8 00000000 00000000 00FD1438 00FD1448 *................* 000002D8 00FD1450 00000000 00000000 00000000 *...&............* 000002E8 00000000 00000000 00000000 00000040 *............... * 000002F8 00000000 00FEBAD0 00000000 00000000 *................* 00000308 5FB1EE40 00040000 00000000 00000000 *^.. ............* 1= HELP 2= 3= END 4= 5= REPEAT 6= 7= BACKWARD 8= FORWARD 9= HIST BWD 10= HIST FWD 11= 12= * * * * * * * * * * * * * * * * * * * * * * * Figure 4. Here you see a storage description of the first TCB, formatted as a TCB by the LOOK program. LOOK COMMAND - DISPLAY VIRTUAL MEMORY DISPLAY ASID= 0029 ENTER CMD - LAST CMD - J+4 009B81F8 TCB FRS0 0000000000000000 FRS2 0000000000000000 FRS4 0000000000000000 FRS6 0000000000000000 RBP 009B8110 PMASK 00 PIEA 000000 DEB 00000000 TIO 009C8000 CMPF 94 CMPC 0C4000 ABF 40 TRNB 000000 MSSB 7547A8 PKF 80 FLGS1 00 FLGS2 00 FLGS3 00 FLGS4 00 FLGS5 00 LMP FF DSP FE LLS 00000000 JLB 0000BF14 PURGE 00 JPQB 000000 GRS0 00E23A78 GRS1 00000009 GRS2 00000318 GRS3 00000003 GRS4 0007E9C0 GRS5 00000000 GRS6 0007F100 GRS7 00023E90 GRS8 00081DE0 GRS9 05A5F7D8 GRS10 0007E518 GRS11 85A5E7D8 GRS12 846C3D18 GRS13 0007E518 GRS14 85A5EAA4 GRS15 00000000 FSAB 07DFB0 TCB 00000000 TME 00000000 JSTCA 9FD178 NTC 00000000 OTC 009D9298 LTC 00000000 IQE 00000000 ECB 0007312C TSFLG 00 STPCT 00 TSLP 00 TSDP 00 RD 7FF16EE4 AE 00000000 NSTAE 00 STABB 9FF410 TCTGF 80 TCTB 9D9D58 USER 00000000 NDSP0 00 NDSP1 00 NDSP2 00 NDSP3 00 MDIDS 00000000 RECDE 00 JSCBB 9FD234 SSAT 00FD35B8 1= HELP 2= 3= END 4= 5= REPEAT 6= 7= BACKWARD 8= FORWARD 9= HIST BWD 10= HIST FWD 11= 12= * * * * * * * * * * * * * * * * * * * * * * * Figure 5. This is the unformatted storage pointed to by the address at X'B4' off the beginning of the previously shown TCB. This is the JSCB or Job Step Control Block. From the formatted TCB display shown previously, we can also get here with a label Link command: LJSCBB. LOOK COMMAND - DISPLAY VIRTUAL MEMORY DISPLAY ASID= 0029 ENTER CMD - LAST CMD - J+B4 009FD234 >00000000 00000000 00000000 00000000 *>................* 009FD244 00000000 009FD2D0 00000000 7FFFED60 *......K....."..-* 009FD254 009FDE88 00000000 00000000 00000000 *................* 009FD264 00000000 00000040 7FFFC02C 7FFDDEB0 *....... "..."...* 009FD274 00000000 E3C3C240 00000000 00000000 *....TCB ........* 009FD284 7FFDD370 0000FFFF 00048000 00000000 *".L.............* 009FD294 00064E78 7FFD6DC0 00000000 7FF16EF4 *..+."._....."1.4* 009FD2A4 7FFDD7F0 00000000 00000000 7FFF5138 *".P0........"...* 009FD2B4 00000000 5A8DF658 00006E88 00000003 *....!.6.........* 009FD2C4 00000000 00000000 00000000 00000000 *................* 009FD2D4 00000000 00000000 0000000C 00000000 *................* 009FD2E4 00000000 00000000 00000000 00000000 *................* 009FD2F4 00000000 00000000 00000000 00000000 *................* 009FD304 009FDE88 00000000 009D9528 00000000 *................* 009FD314 00000000 01000000 00000000 00000000 *................* 009FD324 00000000 009DE940 00000000 00000000 *......Z ........* 1= HELP 2= 3= END 4= 5= REPEAT 6= 7= BACKWARD 8= FORWARD 9= HIST BWD 10= HIST FWD 11= 12= * * * * * * * * * * * * * * * * * * * * * * * Figure 6. The PSCB is X'108' off the previous location, which is the JSCBPSCB field of the JSCB. We could not get to this location with a label Link command, because the previous screen was not formatted as the JSCB control block. We are looking at the storage which is pointed to by the address at that location. Lo and behold, the PSCB can be seen in storage. The PSCBUSER field of the PSCB is 7 bytes long, starting from the beginning of the PSCB control block. And it's got our userid there. In our program, we just have to move these 7 bytes into the TPUT display to the terminal, and we're done. It pays to see what you are doing! LOOK COMMAND - DISPLAY VIRTUAL MEMORY DISPLAY ASID= 0029 ENTER CMD - LAST CMD - J+108 00005F80 >E2C1C7D6 D3D6C207 E2E8E2C1 D3D3C4C1 *>SAGOLOB.SYSALLDA* 00005F90 A2000000 AFA3EAB7 05B5FC00 00000000 *................* 00005FA0 0000006F 00000000 00000000 00000000 *...?............* 00005FB0 00006EC0 00006FC8 00380000 00000C00 *......?H........* 00005FC0 00000000 00000000 00000000 00000004 *................* 00005FD0 00000000 00000000 00000000 00000000 *................* 00005FE0 00000000 00000000 00000000 00000000 *................* 00005FF0 00005FF8 00000000 C9D2D1D3 D1F14040 *..^8....IKJLJ1 * 00006000 00000000 00000000 00000000 00000000 *................* 00006010 00000000 00000000 00000000 00000000 *................* 00006020 00000000 00000000 00000000 00000000 *................* 00006030 00000000 00000000 00000000 00000000 *................* 00006040 00000000 00000000 00000000 00000000 *................* 00006050 00000000 00000000 00000000 00000000 *................* 00006060 00000000 00000000 00000000 00000000 *................* 00006070 00000000 00000000 00000000 00000000 *................* 1= HELP 2= 3= END 4= 5= REPEAT 6= 7= BACKWARD 8= FORWARD 9= HIST BWD 10= HIST FWD 11= 12= * * * * * * * * * * * * * * * * * * * * * * * Figure 7. HELP screen for the LOOK command. This will remind the user of LOOK what can be done. There's really a lot of flexibility, if you study this command set. LOOK COMMAND - DISPLAY VIRTUAL MEMORY DISPLAY ASID= 0029 ENTER CMD - LAST CMD - HELP LOOK is a real time core display and formatting program. It also has the capability of displaying memory in any address space (if authorized). The valid commands are: Iexp 24 bit indirect | Jexp 31 bit indirect > Forward | < Backward =sym Define current address as "sym" | ,sym Redisplay core at "sym" M0/M1 Flip between top and center | Lname Indirect thru control block field Ocb Format as "cb" control block | R Refresh displayed storage "cb" may be NULL to show as hex | where 'exp' is of the form: <+/->hhhh<+/-hhhh<+/-hhhh...>> and 'hhhh' is a 1 to 8 digit hex number.