Hidden treasures in MVS

I want to spread some info that can be very valuable to many people who want to know more about what is really happening in MVS or in their applications. As so often before... all info is there. It is just a matter of knowing where to find it and then to interprete the info. I hope that I can help out here.

One of the greatest places for info in MVS is the system trace table. It contains a lot of information, but don't bother with all info that you do not understand. Stay focused on things you do understand and you will feel a lot better.

MVS has a default trace buffer per processor. These will be formatted as a single trace table by abend routines. How can they be treated as a single trace table? Easy! All trace entry's have a time stamp. All that is needed is to merge the trace tables based on this time stamp. There is much more about time stamping in the TOD links from the header page.

You will typically see the trace when something goes really wrong in MVS or in an application. The trace will be part of the debug marterial (part of the dump). The trace table is like the flight data recorder in an airoplane. It contains vital data from vital instruments at the time of an accident.

The trace data is such a good window into MVS. Why not try to get a view of it without something going bad? Can that be done? Sure. Just include a SNAP macro like this in your assembler program:

PAUL SNAP DCB=SNAP1,SDATA=TRT,STORAGE=(USRLIST,ENDLIST)

At the label PAUL, we have the SNAP macro. We need a DCB that tells us what DD card to use for output. The STORAGE keyword is to tell what part of storage we want dumped to our DD card. But for now, the TRT parameter is what we focus on. The TRT is short for Trace Table. That is about all we need to do. But... MVS is concerned that we can see too much info. If the caller of the snap macro is a normal user, then he will only get trace entry's that belong to his address space. If the caller is autorised (AC=1), then he will receive all the trace info.

Now that we know how to get the trace data out, how do we get some info into it? Normally, you do not need to do anything, since any interrupt (plus some other events) will end up in the system trace. But, we can activate branch trace or activate PER (program event recording) and so get much more into the trace. The drawback is that the trace table will wrap around much faster. You cannot look so far back into history as you would like. All this is also adding overhead to the system.

There is one secret way to get footprints from your program into the trace. Secret?? Well, not really secret, since it was documented in my handbook for OS-360: S229-3169-3 (System/360 Operating System field engineering handbook) from 1971. I seem to remember that it was also mentioned in the VS2-SVS handbook (and I have no copy of it) but no more after that. What is the secret? The NOP SVC. Yes, there is an SVC that does nothing. Yes, it is still there today. Since it is an SVC, it generates an interrupt and so it is traced. This is SVC 50 or 0A32 for real programmers. It can be inserted freely into your code and will leave footprints behind. You may have a separate job that is authorised and only snaps out the trace table on demand and you will be able to see the timestamped footprints from your program.
You will have to do a little research yourself if you want to use this SVC a lot (remember - it is not documented in today's versions of MVS!). Find out if any register contents are damaged across the SVC handling (check E, F, 0 and 1 just to be sure). You may also want to have a look for what registers are saved in the trace entry's. This is a good way to send info to the person using the trace data. You could tell what routine was active or what transaction was active or so. It is up to you.
So, you like this, but it does add a little overhead to the program. Can we enable / disable this feature? Yes, there is always a way, once you have a deep look at it. Just do like this: You have a program that has some kind of control block pointed to during its lifetime. Let's assume that you have reg 8 pointing to this control block all the time. Put the SVC in a free place in this block (assume offset 444). Instead of having SVC's in our program, we will use Execute instructions instead. So, all we do is to insert 44008444 anywhere in our code. Now we execute the SVC and get the footprint. But, if we want, we replace the SVC with a 0700 and we will not do any footprints at all.

There is much more about the TOD clock in a separate link from the header page. For now, just take the TOD value from 2 interesting trace entry's and subtract them from each other. Skip the last 3 characters (the last 12 bits or the last 11/2 byte). Convert this to decimal and you have the difference in time in millionth's of a second. Really easy. Now you can get into program elaps times without really doing any overhead or without any costly monitors.

/Paul Saers
http://paul.saers.com

Reference info:
System trace table: see A22-7585.00 z/OS V1R1.0 MVS Data Areas, Vol 5 (SSAG-XTLST)
Snap macro: see A22-7607.00 z/OS V1R1.0 MVS Programming Assembler Services Reference Vol 2