Creating trace buffers

You need to obtain storage for:
  • The trace buffers, which contain the trace data.
  • The TBWC control area, which contains the status information for a specific buffer.
  • Control information about your buffers, trace status, and user-defined options.
  • An anchor point to control your information.

If you are using an external writer and want to exploit the TESTMODE parameter of the CTRACECS macro, you must initialize the buffer state to available. Either use the CTRACECS macro or set the TBWCCAVL bit to '1'B in the TBWC, mapped by ITTTBWC.

Figure 1 includes an illustration of how an application might organize its control structures to manage the component trace buffers.

Where to locate trace buffers: You should anchor your trace buffers in an area that the CTRACE buffer find exit routine can access when running under IPCS. The anchor is a pointer to your control information, and should be an area of storage addressable by your application at all times that the application is defined to component trace. Component trace supports the location of trace buffers in private, common, or data space storage. In z/OS® V1R8 or a later release, CTRACE limits the length of buffers that may be passed to the trace writer to X'00000000_80000000' bytes. Substantially smaller buffers are generally recommended. Trace entries within any buffer form a list structure. Loss of one page when a dump is recorded or damage to a single byte can render all remaining trace entries illegible.

When to obtain trace buffers: The application has the choice of allocating the trace buffers at initialization time, or waiting until the trace is turned on. If you wait until the trace is turned on, you avoid using system resources unnecessarily. Either the application or the start/stop exit routine can obtain the needed storage.

Determining the size of your trace buffers: You determine the size of your trace buffers based on the number of trace entries you anticipate creating, and the size of the trace entries. You control both of these values.

You can specify the size of your application's trace buffers in the following ways:
  • CTRACE DEFINE with the BUFDFLT parameter
  • TRACE CT,nnnnK or TRACE CT,nnnnM operator command
  • Parmlib member with BUFSIZE keyword.

If you set a default size on CTRACE DEFINE, the value can be overridden on the TRACE CT command or in a parmlib member, provided you also specify BUFFER=YES on CTRACE DEFINE. If you specify BUFFER=NO, which is the default, you do not allow the buffer size to be changed. In this case, the application might allocate too much storage when it is not needed, or allocate too little storage and cause inadequate trace data to be captured when needed.

Changing the trace buffer size: If the application allows trace buffer size to be changed, the application must deal with the serialization concerns associated with the deletion of the old trace buffers in a multitasking environment. For example, if you decide to use a new, larger buffer, you will have to copy all the data from the old to the new buffer. You must ensure that each task writing trace entries is aware of such things as the new buffer address (and possibly ALET) and the new buffer size, and whether the new buffer is in private, common, or data space storage.

Using multiple buffers: You should allocate multiple trace buffers, especially if you plan to use the external writer. In general, the external writer will asynchronously capture a full trace buffer while the application continues processing and writing trace entries to another trace buffer. If your application does not require trace data to be captured asynchronously, then you might be able to use a single, wrapping trace buffer.

Deciding what to include in the control information: You can set up a block of storage to contain whatever control information you require to keep track of your trace buffers. This control information can be in private, common, or data space storage. The following are examples of the fields you might include in your control information:
Current mode
Whether the trace is currently on or off or min.
Active options
Which tracing options are currently active. Consider using a bit mapping where each bit represents a tracing option. Trace points in the code can check one or more of these bits to determine whether tracing is active for this trace point. See Setting up user-defined options for further details.
External writer indication
Whether the application is connected to an external writer. If this flag is set, the application issues the CTRACECS macro to keep track of its trace buffers, and the CTRACEWR macro to write buffers to DASD or tape. The application might also store the token that the start/stop exit routine passes. The start/stop routine obtains the token from the CTSSWTKN field of the CTSS (the parameter list passed to the routine). The application needs this token to issue the CTRACEWR macro.
ASID or JOBNAME lists
If the application supports ASID or JOBNAME filtering, the list of ASIDs or JOBNAMEs can be kept here. When filtering, the application can check these lists against the ASID or JOBNAME current at the time of tracing.
Trace buffer addresses
A table, list, or queue of trace buffer addresses and lengths to track the available trace buffers. If the buffers are in different address spaces or data spaces, keep an access list entry token (ALET) or space token (STOKEN) with the buffer pointer.
Trace buffer writer control (TBWC) area
A TBWC is associated with each trace buffer.
Current buffer address
Address of the buffer that is currently receiving trace entries.
Current entry address
Address of the next available slot in the current trace buffer. If your application supports multitasking, consider using compare and swap to serialize the trace buffer and update the pointer to the following trace entry.