The routines of this complex are provided as the ultima ratio regis for finding program errors which destroy data in a Zebra store by faulty handling of links; they consume a lot of CPU time.
With automatic verification switched on calls to the Zebra system transfer to ZVAUTY, which handles the verification process:
The "verify identifier" (VID
) is constructed by counting the number
of entries to ZVAUTY.
The VID
is a two-word object, because 32 bits
may not be sufficient, it identifies every call to Zebra, it gives
us a handle on where we are in the job, and it is available to the
user via the common /ZVFAUT/ to be printed together with the event
number, for example.
ZVAUTY will remember separately the VID
for the
last garbage collection, for the last MZWIPE, and for the last FZIN,
for printing on fatal error.
In "active mode" ZVAUTY will call ZVERIF for the stores selected by the user initially, causing a transfer to ZFATAL in case of trouble, which in turn will transfer control to the user by calling ZABEND, where he may code any display wanted.
In "dummy mode" the time-consuming calls to ZVERIF will not take place,
but the VID
is checked to see whether the "action threshold" defined
by the user is reached. If so, the mode is switched to "active", and
the log-level is set for all stores to be verified.
From this point on one may get rather a lot of output, tracing the
execution of the program step-by-step.
Suppose now one has a particular run, "run A" say, of a lengthy
production job which collapses with the memory destroyed.
The reason for this will be somewhere in the past.
One could re-submit the job switching on true automatic verification
right away, but this could be excessively time consuming and produce
much too much output.
If so, it is better to re-submit the job first with "dummy verification"
switched on by inserting a call to ZVAUTO at the point where one wants
to start verification, after the initialization phase for example,
and with the connection routine ZVAUTX supplied,
"run B" say.
Dummy verification goes through the
same motion as active verification, but it does not call ZVERIF
and hence costs only little more time than run A. This run should also
end up in ZFATAL, which will now print the VID
's remembered for the last
garbage collection, for the last wipe, for the last FZIN,
and maybe other VID
's entered by the user with ZVAUTU.
One can now re-submit the job, "run C" say, having changed the call to ZVAUTO by giving the action threshold, thereby defining the moment when active verification will start.
Automatic verification is initiated with
CALL ZVAUTO (MSTORE,IDVTH1,IDVTH2,LOGLEV)
with MSTORE a bit-by-bit word indicating the stores to be verified, store i = 0,1,2,... selected if bit (i+1) is set to one; if MSTORE = 0: all stores IDVTH1/2 the two-word VID at which true verification should start, give both words zero if dummy verification only ("run B" in the discussion above); give 0,-1 if active verification is to start right away; LOGLEV set the log-level of the existing stores to be verified to this value at the moment of changing to active mode, give 2 for maximum logging.
To avoid loading the non-negligeable code of the ZVAUTO complex with normal production jobs, this trick is used: all relevant Zebra routines contain a conditional call to ZVAUTX (which does not take place if ZVAUTO has not been called), and the Zebra library contains a dummy routine ZVAUTX. But the true process is controlled by ZVAUTY, which is not normally loaded. The user makes the connection by supplying this routine:
SUBROUTINE ZVAUTX CALL ZVAUTY ENDas part of the material to be compiled and linked.
In the list of "last VID
s remembered" there are 3 places for user
triggered storage, which is done with
This will push the VID
in position 2 to position 3, and the one in
position 1 to position 2, entering the current VID
into position 1.
Thus, if one were to call ZVAUTU at the start of each event,
one would see the start points of the last 3 events in a dump
from ZFATAL.
The user has access to the verification parameters via this common:
COMMON /ZVFAUT/IQVID(2),IQVSTA,IQVLOG,IQVTHR(2),IQVREM(2,6) IQVID the current VID IQVSTA the verification status: zero automatic verifying not running -1 dummy verification +1 active verification IQVLOG the log level to be set at the activation threshold IQVTHR the threshold VID IQVREM(2,J) VID remembered in position J, J = 1 last garbage collection 2 last call to MZWIPE 3 last call to FZIN 4 last call to ZVAUTU 5 last-but-one call to ZVAUTU 6 last-but-two call to ZVAUTU
Examples:
Do not forget to supply the connection routine ZVAUTX ! CALL ZVAUTO (7,0,0,0) to start a dummy verification run for store numbers 0, 1, 2; "run B" of the discussion above. Supposing that the ZFATAL output of this run tells us the VID of the last-but-one event, by changing to CALL ZVAUTO (7,0,123456,2) we may start "run C" to give detailed logging for the last two events. CALL ZVAUTO (1,0,-1,0) to start an active verification run for store number 0; one might do this on a limited data sample before going into production with a new program, just to verify that the program is alright.