The first part of this tip outlined some basic information about the mainframe’s Serviceability Level Indication...
Processing. This column will delve into the SLIP command and provide a couple of samples.
The SLIP command, as documented in z/OS System Command reference, is complicated and cantankerous. It has many — somewhat contradictory — options. A few appear to overlap if you don’t read the documentation closely enough.
There are three different types of SLIP commands:
- SLIP SET creates a trap
- SLIP MOD modifies an existing trap
- SLIP DEL deletes an existing trap
This tip will only use SLIP SET commands.
There are global parameters that apply to all the SET command’s forms. The first is ID, which allows you to assign a 4 byte label to the SLIP trap that subsequent MOD or DEL commands can refer to. It is optional and the system will generate an ID if you do not provide one.
The MATCHLIM parameter denotes how many times the SLIPs condition will match before the system disables it. Its maximum depends on the action of the trap. Dump actions get a default of 1. Other action types can have a higher MATCHLIM, but it’s always best to consult the documentation for the values pertaining to a specific action.
A SLIP command must be terminated with the END parameter. If the system doesn’t see END, it issues a Write to Operator with Reply (WTOR) message asking for more input; the user can reply with additional parameters. This will continue unit the user explicitly terminates the command with END. This is handy for SLIPs with specifications that may be longer than a single command line.
Finally, note that the designation for Program Event Recording (PER) traps, which includes Storage Alteration (SA), Instruction Fetch (IF) and Successful Branch (SBT), is positional and must follow the SET operand. Otherwise, for non-PER SLIPs, the operands, with the exception of END, can be in any order.
The SLIP command provides flexible memory address expressions. A register specification is a number, 0 through 15, followed by an R. For instance, 3R refers to register 3. Indirect address expressions follow some conventions of Interactive Problem Control System (IPCS). Different unary operators tell the system to interpret an address as 24 bit (“%”), 31 bit (“?” ) or 64 bit (“!”). In addition you may specify offsets to anywhere along the chain with a plus sign.
By way of example:
|3CDEF034||An absolute virtual address within the target address space|
|0R?+4||Refers to the memory location 4 bytes after the pointer in register 0|
|3CDEF034?+4?+C||Specifies the address 12 bytes from the pointer 4 bytes after the location at virtual address 3CDEF034|
Lastly, there are a couple symbolic names for control registers. For instance, BEAR refers to the Breaking Even Address Register.
A batch program gets a storage addressing exception (0C4), but various recovery routines mask the problem’s origin.
This may be the easiest type of SLIP because all we have to specify is the job name and the completion code:
The completion (COMP) parameter tells SLIP to spring when an 0C4 occurs in job WILLFAIL and ACTION=SVCD produces a dump. However, this trap may spring if the program creates an addressing exception during an ordinary page fault. Adding the program thought to cause the problem may avoid false positives, thus:
A utility program to convert Julian dates to MMDDYYYY format isn’t working correctly. There is no ABEND associated with the error. We suspect the calling module, which invokes the utility hundreds of times in each run, is passing a bad input date. Since we don’t know which call provides the bad date we’ll have to monitor the program while it runs.
From the source code we know the bad parameter would be at offset +0 from the address in register 1 as control passes into the utility program.
Dumps aren’t appropriate in this case. Instead we’ll use an IF trap that springs on the first instruction of utility module CONVDATE. We also use ACTION=TRACE to write debugging information to system trace where we can pick it up with the General Trace Facility (GTF) writer. Finally, the TRDATA parameter tells SLIP what we want to capture.
From this information we craft this command:
After setting the SLIP we start the GTF writer and run the job. When the job finishes we format the trace with IPCS. Each trace entry should contain the first 16 bytes of the storage addressed by register 1.
A misbehaving CICS program overlays part of its save area with the character string, “Ha-Ha!” We also know the program where the overlay occurs. To debug this problem we need a SA SLIP that dumps the CICS address space when it sees the overlay.
Unfortunately, since CICS manages the program, we will have to use the RANGE parameter to tell SLIP what instructions to monitor. To get the proper address we can use one of my favorite tricks, CICS’ Execute Command Interpreter (CECI). With CECI we can issue a LOAD command for the program and pluck its entry point from the results. That, and the program’s length, gives us the information needed for RANGE.
CECI tell us the program is loaded at address 3CBDF000 and has a length of 32,000 bytes. From previous CICS storage violation dumps we know the overlay occurs at offset +1C into the save area. The command to use is:
SLIP SET,SA,RANGE=(3CBDC000, 3CBE3D00),DATA=(13R?+1C,EQ,C’Ha-Ha!’,ACTION=SVCD,ENABLE,END
Once the trap springs we format the dump with IPCS where the Program Status Word (PSW) at the time of the error should point to the instruction that caused the overlay.
ABOUT THE EXPERT: Robert Crawford has been a systems programmer for 29 years. While specializing in CICS technical support, he has also worked with VSAM, DB2, IMS and other mainframe products. He has programmed in Assembler, Rexx, C, C++, PL/1 and COBOL. The latest phase in his career finds him an operations architect responsible for establishing mainframe strategy and direction for a large insurance company. He works in south Texas where he lives with his family.