SLIP zero address detection (ZAD)
A Zero Address Detection (ZAD) event is a PER program interrupt caused by execution of an instruction that accesses (stores or fetches) storage using an operand address that was formed from a general register containing zero, when the PSW PER bit is on and Zero Address Detection is enabled. You enable Zero Address Detection by a SLIP PER trap of type ZAD. A ZAD trap can help to detect errors that involve unintentionally referencing the PSA. All instruction ranges are monitored for ZAD events; you can limit ZAD events only by limiting the address spaces and jobs for which PER is active. You can limit the ZAD events that match your SLIP traps by using other SLIP filtering keywords.
A SLIP PER ZAD trap must be used with caution. Due to normal system processing, many expected ZAD events in IBM modules can occur, which do not represent problems and are not defects. Due to these expected ZAD events, there can be noticeable system overhead when using a SLIP ZAD trap. More efficient use of ZAD events could be achieved on a test system rather than a production system, assuming the test system can tolerate higher system overhead from a SLIP trap.
- Use filtering keywords with a SLIP ZAD trap.
- Avoid unwanted matching of the SLIP ZAD trap.
- Limit the address spaces and jobs that SLIP monitors by using the ASID and JOBNAME keywords.
- Limit the address range of the instruction that causes the ZAD interrupt, by using the ADDRESS, NUCMOD, LPAMOD/LPAEP or PVTMOD/PVTEP keywords.
- Limit the address ranges by using IGNORE ZAD traps that specify the ADDRESS keyword, so that matches occur only within your modules. For example, if you have two address ranges to monitor for ZAD events you could use IGNORE ZAD traps to filter out everything else. As a specific example, to monitor addresses 10000000-20000000 and 30000000-40000000, you could set IGNORE ZAD traps for addresses 0-FFFFFFF, 20000001-2FFFFFFF and 40000001-7FFFFFFF. The non-IGNORE trap only matches if the event occurs outside of the three IGNORE ranges, which in turn is within the two ranges that you are focusing on. When setting IGNORE traps, you must follow the documented protocol for setting them after setting the non-IGNORE trap, and enable the non-IGNORE trap only after the IGNORE traps are enabled.
- Use ASIDSA=SA to filter the expected ZAD events when page 0 of a data space is referenced using a base register with a 0 value, which would occur when using the ORIGIN returned by DSPSERV CREATE.
- Use other filtering keywords, such as DATA, when appropriate.
- Taking an SVC Dump
- Creating a GTF record
- Creating a system trace record
- Collecting data and getting a report of all ZAD events.
Even a properly limited trap can still collect many ZAD events. As with any PER trap, the PRCNTLIM keyword limits the amount of system processing that the trap can use. If that amount is exceeded, SLIP automatically disables the trap. If using the default or a lower PRCNTLIM value resulted in SLIP automatically disabling the trap, and your system can tolerate the additional overhead, you can try a higher PRCNTLIM value. If the SLIP still automatically disables the trap, then you cannot use a SLIP ZAD trap to monitor that particular event on that system.
When testing, look for ZAD events only within your own product code. If you see a ZAD event that is outside of your product code, and you do not suspect that it is an error, do not report it. If your product code only runs in a limited set of address spaces or jobs, you can limit the address spaces or jobs in which PER events can occur.
To use ZAD, you must be running z/OS on a z196, z114 or later server model. ZAD is not supported on z/OS under z/VM.
- Set up a procedure named IEAVTSZR, as shown in Figure 1.
- START IEAVTSZR, which initializes an area to record the information.
- Run SETPROG LPA,ADD,DSN=SYS1.LINKLIB,MOD=IEAVTSZE,FIXED. Alternatively, you could use the FLPA system parameter with an IEAFIXxx parmlib member to complete this step during IPL.
- Issue the following system command, which sets a SLIP trap named ZAD1: SLIP SET,ZAD,A=AEXIT,AEXIT=IEAVTSZE,ID=ZAD1,PL=50,OK,END. Although A=AEXIT and the AEXIT keyword are not otherwise documented, this specific use is permitted. You can change the PL value, use a different ID and add other SLIP filtering keywords prior to END when setting this SLIP trap.
- Run your programs.
- Run START IEAVTSZR. In this instance, the command writes a report for all ZAD events to SYSPRINT, and then resets to continue.
- If necessary, run additional iterations of the running programs and the START IEAVTSZR command.
- Run START IEAVTSZR,OP=FREE. You can skip this step if you are doing an IPL.
To the extent possible, the report identifies where the event occurred (by address and by module name, if available), how many times the event occurred, and the instruction that was issued. This facilitates locating the particular module and determining if the event is an error. If you find non-error events within your product code, you could modify the code to avoid reporting the non-error event. You could also add ASIDSA=SA to the SLIP trap to avoid hits for data space stores. The report flags data space stores with a "D", however, so they can be ignored.
You can add further modifiers to your SLIP trap to avoid reporting additional events, using LPAMOD, NUCMOD, ASID and ADDRESS, for example. The ZAD events will still occur, but SLIP will filter them out and the trap will not match.
//********************************************************************
//** SIZE may be nK, nnK, nnnK, nM, nnM, nnnM. It is the amount of *
//** fixed, common storage to be used for individual instruction *
//** data. It is added to the amount needed to capture data for *
//** every address space. *
//** *
//** OP=FREE indicates that you're done *
//** OP=DATA indicates *
//** - Allocate if not yet allocated *
//** - Produce a report based on the current data *
//** - After producing a report, clear the data *
//** Do not specify STATS. Leave it as YES *
//********************************************************************
//IEAVTSZR PROC SIZE=1M,OP=DATA,STATS=YES,SYSOUT=*
//IEAVTSZR EXEC PGM=IEAVTSZR,TIME=1440,REGION=0M,
// PARM='OP=&OP,SIZE=&SIZE,STATS=&STATS'
//SYSPRINT DD SYSOUT=&SYSOUT