The ptrace callable service provides information about another process and controls its running. Use this service in debugger programs to do breakpoint debugging.
Operation | Environment |
---|---|
Authorization: | Problem Program, PSW key 8 |
Dispatchable unit mode: | Task |
Cross memory mode: | PASN = HASN |
AMODE (BPX1PTR): | 31-bit |
AMODE (BPX4PTR): | 64-bit |
ASC mode: | Primary address space control (ASC) mode |
Interrupt status: | Enabled for interrupts |
Locks: | Unlocked |
Control parameters: | All parameters must be addressable by the caller and in the primary address space. |
|
AMODE 64 callers use BPX4PTR with the same parameters. The Address, Data, and Buffer parameters are doublewords.
The name of a fullword that contains one of the integer values that indicates the function requested. The request integer values are defined in the BPXYPTRC macro. See BPXYPTRC — Map parameters for ptrace.
The name of a fullword that contains the process identifier of the process that is the target of the ptrace call, or 0 for the PT_TRACE_ME, PT_EXTENDED_EVENT, and PT_RECOVER requests.
The name of a fullword (doubleword) that contains a value that is identified by the option selected for the Request parameter. For a mapping of this parameter to the Request parameter options, see Table 4.
The name of a fullword (doubleword) that contains a value that is identified by the option selected for the Request parameter. For a mapping of this parameter to the Request parameter options, see Table 4.
The name of a fullword (doubleword) that contains a value that is identified by the option selected for the Request parameter. For a mapping of this parameter to the Request parameter options, see Table 4.
The name of a fullword in which the ptrace service returns 0; the requested value if the request is successful; or -1 if it is not successful. For more information about values that are returned for specific requests, see Table 5. A value of -1 is sometimes returned when the request is successful. For example, if a general-purpose register contains a value of -1, a PT_READ_GPR request returns this value in the Return_value parameter.
Return_code | Explanation |
---|---|
EAGAIN | One or more resources are temporarily unavailable. Reissue the request at a later time. |
ECHILD | The debugged process ended while a ptrace service request was running. |
EFAULT | An address in the caller's process is incorrect. The following reason codes can accompany the return code: JRBadAddress, JRPtInvDbrAddress. |
EINTR | The ptrace service request was interrupted by a signal for the caller. |
EINVAL | The request was not accepted, for one of the following reasons:
The following reason codes can accompany the return code: JRPtLDBufferTooSmall, JRBuffTooSmall, JRNotPage, JRPtBufNotFound, JRPtInvLength. |
EIO | The request was not accepted for one of the following reasons:
The following reason codes can accompany the return code: JRPtAttemptedCRStore, JRPtAttemptedPSW0Store, JRPtDbdParentTerm, JRPtDbrPidNotFound, JRPtDbrZombie, JRPtInvCallingMode, JRPtInvDbdAddress, JRPtInvFPRNumber, JRPtInvGPRNumber, JRPtInvNumberThreads, JRPtInvPtraceState, JRPtInvRequest, JRPtInvSignalNumber, JRPtInvUAreaOffset, JRPtOldDbrPidNotFound, JRPtThreadTerm, JRPtLightWeightTHID, JRPtThreadNotFound, JRPtTSO, JRPtRequestDenied, JRPtAsyncThread, JRPtNotXtdEvent, JRPtTooManyEvents, JRPTInvVRNumber. |
EMVSSAF2ERR | For the PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests, the caller does not have the appropriate privileges to debug the target process. For information about appropriate privileges, see Authorization. |
ENOMEM | There is not enough storage available to satisfy a PT_CAPTURE request. |
EPERM | Permission to issue the request is denied for one of the following
reasons:
The following reason codes can accompany the return code: JRPtRestrictedProcess, JRPtEdIsAuthorized. |
ESRCH | The request was not accepted, for one of the following reasons:
The following reason codes can accompany the return code: JRPtDbdEqualsDbr, JRPtDbdPidNotFound, JRPtProcessNotPtraced, JRPtProcessNotStopped, JRPtDbrParentEqualsDbd. |
RACF return code | RACF reason code | Explanation |
---|---|---|
8 | 4 | The caller is not authorized to attach to the target process |
8 | 12 | Internal error during RACF processing |
Table 3 shows the constant options that you can select for the Request parameter. See BPXYPTRC — Map parameters for ptrace for the constant definitions.
Constant | Explanation |
---|---|
PT_ATTACH | Enable a target process to be debugged with the ptrace service. |
PT_CAPTURE | Capture one or more pages of storage in the target debugged process into a buffer in the caller's address space. |
PT_CONTINUE | Continue running the debugged process. |
PT_DETACH | Disable debugging for the target process. |
PT_EVENTS | Enable or disable reporting for an extended event. |
PT_EXPLAIN | Return additional information about an extended event. |
PT_EXTENDED_EVENT | Notify the debugger of an extended event. For more information, see Handling a program check or abend in a debugged process. |
PT_KILL | End the debugged process. |
PT_LDINFO | Return information about modules that were loaded by the debugged process. |
PT_MULTI | Turn multiprocess debugging mode on or off. For information about multiprocess debugging, see Multiprocess debugging mode. |
PT_BLOCKREQ | Several Ptrace request types are blocked together into a single Ptrace call. |
PT_READ_BLOCK | Read a block of storage. |
PT_READ_D | Return a fullword of data from a specified address in the debugged process. This request reads program data. |
PT_READ_FPR | Return the value of a floating-point register. |
PT_READ_GPR | Return the value of a general-purpose or machine-control register. The value includes the PSW and control registers, as well as general-purpose registers. |
PT_READ_GPRH | Read a specific general-purpose high register. |
PT_READ_I | Return a fullword of data from a specified address in the debugged process. This request reads program instructions. |
PT_READU | Return the value of a fullword of control information from the user area in the debugged process. For more information, see User area description. |
PT_READ_VR | Return the 16-byte value of a vector register. |
PT_WRITE_VR | Change the 16-byte value of a vector register. |
PT_REATTACH | Enable a target process to be debugged with the ptrace service by a new debugger. The relationship between the target process and its original debugger is removed. |
PT_REATTACH2 | Enable a target process to be debugged with the ptrace service by a new debugger. The relationship between the target process and its original debugger is removed. This request is an extension of the PT_REATTACH request, and must be used by a debugger to deal with the local fork child environment. For more information, see Attaching to a process for debugging. |
PT_RECOVER | Notify the debugger of a program check interrupt or abnormal end. For more information, see Handling a program check or abend in a debugged process. |
PT_REGHSET | Read all of the general-purpose high registers. |
PT_REGSET | Return the values of all general-purpose registers. |
PT_THREAD_HOLD | Hold or unhold a thread in the debugged process. |
PT_THREAD_INFO | Return kernel information on all threads in the debugged process. |
PT_THREAD_MODIFY | Modify a thread's kernel information. |
PT_THREAD_READ_FOCUS | Return the current focus thread ID. |
PT_THREAD_SIGNAL | Queue a signal to a thread in the debugged process. |
PT_THREAD_WRITE_FOCUS | Change the current focus thread ID. |
PT_TRACE_ME | Enable the calling process to be debugged with the ptrace service. |
PT_UNCAPTURE | Free one or all buffers that contain captured storage from previous PT_CAPTURE requests. |
PT_WRITE_BLOCK | Change the contents of a block of storage. |
PT_WRITE_D | Change a fullword of data at a specified address in the debugged process. This request changes program data. |
PT_WRITE_FPR | Change the value of a floating-point register. |
PT_WRITE_GPR | Change the value of a general-purpose or machine-control register. The value includes the PSW and control registers, as well as general-purpose registers. |
PT_WRITE_GPRH | Write to a specific general-purpose high register. |
PT_WRITE_I | Change a fullword of data at a specified address in the debugged process. This request changes program instructions. |
Table 4 shows the ptrace service options for the Request parameter. For each option, the meanings of the Address, Data, and Buffer parameters are shown. Explanations of the terms in the table follow the table:
Request options | Address | Data | Buffer |
---|---|---|---|
PT_ATTACH | 0 | 0 | 0 |
PT_CAPTURE | Capture Address | Capture Length | 0 |
PT_CONTINUE | 1 = Continue from where process stopped Not 1 = Continue Address |
0 = No signal Not 0 = Signal Number |
0 |
PT_DETACH | 0 | 0 = No signal Not 0 = Signal Number |
0 |
PT_EVENTS | Extended Event Id | 0 = Disable re- porting this event Not 0 = Enable reporting this event |
Maximum Events |
PT_EXPLAIN | Buffer Address (destination) | Length | 0 |
PT_EXTENDED_EVENT | GIParm Address | Extended Event ID | Destination Address (4 bytes) |
PT_KILL | 0 | 0 | 0 |
PT_LDINFO | Buffer Address (Destination) | Length | 0 |
PT_MULTI | 0 | 0 = Reset multi- process mode Not 0 = Set multiprocess mode |
0 |
PT_BLOCKREQ | Buffer Address (source / destination) | Length | Buffer Address (destination) |
PT_READ_BLOCK | Debugged Address | Length | Buffer Address |
PT_READ_D | Debugged Address | 0 | 0 |
PT_READ_FPR | Destination Address | Register Number | 0 |
PT_READ_GPR | Register Number | 0 | 0 |
PT_READ_GPRH | Register Number | 0 | 0 |
PT_READ_I | Debugged Address | 0 | 0 |
PT_READ_U | Target Offset | 0 | 0 |
PT_READ_VR | Destination address | Register number | 0 |
PT_REATTACH | 0 | 0 | 0 |
PT_REATTACH2 | 0 | 0 | Destination Address |
PT_RECOVER | PCParm Address | 0 | 0 |
PT_REGHSET | Destination Address | 0 | 0 |
PT_REGSET | Destination Address | 0 | 0 |
PT_THREAD_HOLD | Thread ID Address | 0 = Unhold thread Not 0 = Hold thread |
0 |
PT_THREAD_INFO | Buffer Address | Length | Destination Address |
PT_THREAD_MODIFY | Thread ID Address | 0 | Source Address |
PT_THREAD_READ_FOCUS | Thread ID Address | 0 | 0 |
PT_THREAD_SIGNAL | Thread ID Address | Signal Number | 0 |
PT_THREAD_WRITE_FOCUS | Thread ID Address | 0 | 0 |
PT_TRACE_ME | 0 | 0 | 0 |
PT_UNCAPTURE | 0 = Free all buffers Not 0 = Capture Buffer |
0 | 0 |
PT_WRITE_BLOCK | Debugged Address | Length | Buffer Address |
PT_WRITE_D | Debugged Address | Integer Value | 0 |
PT_WRITE_FPR | Source Address | Register Number | 0 |
PT_WRITE_GPR | Register Number | Register Value | 0 |
PT_WRITE_GPRH | Register Number | Register Value | 0 |
PT_WRITE_I | Debugged Address | Integer Value | 0 |
PT_WRITE_VR | Source address | Register number | 0 |
The PT_CONTINUE request can indicate a value of 1 instead of an address that indicates where continuation should begin. This value, which is defined in the BPXYPTRC macro, indicates that the program should continue from where it stopped.
The length of the thread ID is 8 bytes.
Table 5 shows the ptrace service requests. For each request, the value that is returned in the Return_value parameter is shown. Possible values returned in the Return_code parameter are also shown.
Request | Return_value | Return_code |
---|---|---|
(General) | 0 | EFAULT, EIO, EMVSERR |
PT_ATTACH | 0 | EAGAIN, ECHILD, EIO, EMVSSAF2ERR, EPERM, ESRCH |
PT_BLOCKREQ | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EINVAL, EPERM, ESRCH |
PT_CAPTURE | Capture buffer address | EINVAL, EIO, ENOMEM |
PT_CONTINUE | Value of Data parameter | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_DETACH | 0 | EAGAIN, ECHILD, EINTR, EIO, ESRCH |
PT_EVENTS | 0 | ESRCH |
PT_EXPLAIN | 0 | EFAULT, EIO, ESRCH |
PT_EXTENDED_EVENT | 0 | EFAULT |
PT_KILL | 0 | EAGAIN, ECHILD, EINTR, ESRCH |
PT_LDINFO | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EINVAL, EPERM, ESRCH |
PT_MULTI | 0 | ESRCH |
PT_READ_BLOCK | Value of Data parameter | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EINVAL, EPERM, ESRCH |
PT_READ_D | Fullword value | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_READ_FPR | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EPERM, ESRCH |
PT_READ_GPR | Register contents | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_READ_GPRH | Register contents | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_READ_I | Fullword value | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_READ_VR | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EPERM, ESRCH |
PT_READ_U | Fullword value | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_REATTACH | 0 | EAGAIN, ECHILD, EIO, EMVSSAF2ERR, EPERM, ESRCH |
PT_REATTACH2 | 0 | EAGAIN, ECHILD, EIO, EMVSSAF2ERR, EPERM, ESRCH |
PT_RECOVER | 0 | EFAULT |
PT_REGHSET | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EPERM, ESRCH |
PT_REGSET | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EPERM, ESRCH |
PT_THREAD_HOLD | 0 | EFAULT, EIO, ESRCH |
PT_THREAD_INFO | 0 | EFAULT, EINVAL, ESRCH |
PT_THREAD_MODIFY | 0 | EFAULT, EINVAL, EIO, ESRCH |
PT_THREAD_READ_FOCUS | 0 | EFAULT, ESRCH |
PT_THREAD_SIGNAL | 0 | EFAULT, EIO, ESRCH |
PT_THREAD_WRITE_FOCUS | 0 | EFAULT, EIO, ESRCH |
PT_TRACE_ME | 0 | EAGAIN, EIO |
PT_UNCAPTURE | 0 | EINVAL |
PT_WRITE_BLOCK | Value of Data parameter | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EINVAL, EPERM, ESRCH |
PT_WRITE_D | 0 | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_WRITE_FPR | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EPERM, ESRCH |
PT_WRITE_GPR | Value of Data parameter | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_WRITE_GPRH | Value of Data parameter | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_WRITE_I | 0 | EAGAIN, ECHILD, EINTR, EIO, EPERM, ESRCH |
PT_WRITE_VR | 0 | EAGAIN, ECHILD, EFAULT, EINTR, EIO, EPERM, ESRCH |
Typically, a debugger program starts a process to be debugged by calling the fork service to create a child copy of the debugger program. The child then calls the ptrace service with a PT_TRACE_ME request. This puts the child process into debugging mode. Next, the child calls the exec service to run the program to be debugged.
The PT_TRACE_ME request, along with PT_EXTENDED_EVENT and PT_RECOVER, is issued from the process to be debugged. All other ptrace service requests are issued from the debugger. It is also assumed that the parent of the process issuing a PT_TRACE_ME request is the debugger.
The ptrace service also provides a means for a debugger program to debug an already running, possibly unrelated, process. To do this, the debugger calls ptrace with a PT_ATTACH service request. There are certain restrictions on which processes can be attached (see Characteristics and restrictions). The caller must have the appropriate privileges (see Authorization) to attach to a running process.
The PT_REATTACH request performs a similar function, but is intended to be used in a situation where another debugger process is already attached to the target process. The PT_REATTACH request causes the relationship between the other debugger and the target process to be severed. The caller of PT_REATTACH becomes the new debugger associated with the target process. The PT_REATTACH2 request is identical to PT_REATTACH except in one respect. PT_REATTACH2 provides the address of an area in which return information concerning the reattach can be placed. If the PT_REATTACH2 request is issued against the child process that was created with an attach_exec or attach_execmvs service (a local fork child), the return information is nonzero, indicating to the debugger that alternate reattach processing is required. Otherwise, the return information is zero, telling the debugger that reattach processing should be the same as for PT_REATTACH.
Here is an example of using the PT_REATTACH or PT_REATTACH2 request: Debugger 1 is currently debugging program A in multiprocess mode. For information about multiprocess debugging, see Multiprocess debugging mode. Program A uses the fork service to create a child process, which becomes program B. Debugger 1 is informed of the fork from both the parent (program A) and child (program B) processes. Debugger 1 uses the fork service to create a new debugger, which becomes debugger 2. Debugger 2 then uses the PT_REATTACH request to associate itself with program B. At this point, debugger 1 is debugging program A, and debugger 2 is debugging program B.
The PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests cause a SIGTRAP signal to be sent to the target process. This causes a ptrace service signal event to occur if no other event occurs naturally.
Table 6 summarizes the events and the corresponding status reported to the debugger from the wait call:
ptrace event | Debugger wait service Status_field parameter |
---|---|
Signal received | Signal number |
exec service issued | SIGTRAP signal number or WastStopFlagExec |
fork service issued | WastStopFlagFork |
attach_exec or attach_execmvs service issued | WastStopFlagLocalFork |
spawn service issued | WastStopFlagFork (parent), WastStopFlagLocalFork (child) |
SVC 144 instruction performed | SIGTRAP signal number |
Program check or abend encountered | SIGILL, SIGSEGV, SIGFPE, or SIGABND signal number |
Extended event encountered | WastStopFlagExtended |
When a process has multiple threads, any thread that encounters one of the ptrace service events causes the process to enter a stopped state. This is accomplished by synchronously suspending all other threads in the process. The thread on which the event occurred is known as the focus thread. Because delays could occur between the time the focus thread encounters the ptrace event and the time all the nonfocus threads are suspended, one or more of these other threads could encounter the same or other ptrace events. For instance, several threads could reach a breakpoint in a routine that is common to them all. This creates a situation in which the focus thread is "in control" of ptrace processing, but other ptrace service events are pending. See Working with threads in a debugged process for more information about handling threads in a debugged process.
While the debugged process is stopped for one of the foregoing events, the debugger can issue ptrace service requests to examine or modify registers, storage, and so on. Most ptrace service requests are issued while the debugged process is stopped for the ptrace service event. Examples are: PT_LDINFO and PT_READ_U. An event ends when a PT_CONTINUE, PT_DETACH, or PT_KILL request is issued. One exception to this is a PT_CONTINUE request with a signal that stops the debugged process (for instance, SIGSTOP). In this case the original event does not end until a PT_CONTINUE is issued with either no signal or a SIGCONT. This is because of the ambiguous nature of a "continue and stop" request. The debugged process does not actually continue running until it is taken out of the stopped state, either explicitly by a PT_CONTINUE with SIGCONT request, or implicitly by a PT_CONTINUE with no signal.
Several ptrace service requests can assist debuggers in handling multiple threads. The PT_THREAD_INFO service request returns a list of threads and kernel information about each thread, such as its state (active, dead, and so on) and kernel attributes. The PT_THREAD_READ_FOCUS service request returns the current focus thread ID. These ptrace service requests allow the debugger to gather various thread-related information whenever the debugger is awoken for a ptrace service event.
Certain debugger objectives require exact control over which thread or threads are running at any given time. For example, if the debugger wants to single-step the focus thread, the focus thread must be the only thread in the target process that is running. If this is not so, unpredictable results could occur. The PT_THREAD_HOLD service request allows the debugger to selectively place any threads that are not in a dead state into a held state. When a thread is held, it does not run until it is released. The debugger could therefore use this request to hold all but the focus thread, and then single-step the focus thread by inserting breakpoints after each program statement. The PT_THREAD_HOLD service request can also be used to release threads.
The debugger might also want to work with threads other than the current focus thread. An example might be if the current focus thread manipulates data in shared storage that is then acted upon by a different thread. In order to work with this other thread, the debugger must release the thread, and then shift focus to it by using the PT_THREAD_WRITE_FOCUS service request. This request causes the specified thread to become the new focus thread if it is in an active, non-asynchronous state. Other ptrace service requests that read or write storage, registers, and other data always act against the current focus thread, so this is the means by which the debugger specifies which thread is the target of these other requests.
If the debugger needs to determine the names and entry points of modules that are loaded into the debugged process, it uses the ptrace PT_LDINFO service request. A structure is returned to the debugger that contains information about loaded modules, including the name of the directory that contains the load module for each module loaded from the file system. (The directory name is not returned for modules loaded from MVS™ data sets.) One use for this information is to read the load module library file to obtain symbolic debugging information. The returned structure is defined in the BPXYPTRC macro. For more information about PT_LDINFO, see MVS-related information.
When program checks or abnormal ends occur in a debugged process and are captured by the program's recovery routine (such as an ESPIE or ESTAE exit), the PT_RECOVER request can be issued. This request allows the ptrace service to stop the process and notify the debugger that a program check or abnormal end has just occurred. The caller does not need to determine if the process is being debugged; it can issue the PT_RECOVER request unconditionally. If the process is not being debugged, the returned information indicates to the caller that it can continue as it normally would. The returned information contains PtPICFlags, which are all zeros on return if the process is not being debugged.
The environment information (registers and PSW) can be modified by the debugger by using appropriate ptrace service requests while the debugged process is stopped for the ptrace service event. When the program is continued with the PT_CONTINUE or PT_DETACH request, you need to ensure that any modifications are reflected in the operating environment when the program resumes control.
Language Environment® supports a generic debugger interface for the high-level languages it supports, such as C. This interface requires that a module named CEEEVDBG be available for Language Environment to load and call when certain events occur in a high-level language program that has had this interface enabled via a TEST run time option. The input to CEEEVDBG is a parameter list that contains an event code and information that is associated with that code.
The PT_READ_VR and PT_WRITE_VR requests are used for the vector registers, and this interface supports 16 bytes. All the register numbers are defined in the BPXYPTRC macro.
The PT_READ_FPR and PT_WRITE_FPR requests are used for the FPRs, and this interface supports 8 bytes. In addition to reading and writing the floating point registers, you can also read and write the floating point control register. All the register numbers are defined in the BPXYPTRC macro.
Two special cases exist. One is the PT_REGSET request, which returns all the general-purpose registers. The second is the PT_CONTINUE request, which can indicate that the program should continue at a specified address. In other words, that the instruction counter should be modified.
The second form is for blocks of storage, up to a defined maximum length. For this, the PT_READ_BLOCK and PT_WRITE_BLOCK requests are used. The maximum defined length is defined in the BPXYPTRC macro.
You can use the PT_WRITE_I (or PT_WRITE_D or PT_WRITE_BLOCK) request to store SVC 144 instructions into a debugged program. The SVC 144 instruction causes an SVC 144 event to be recognized by the debugger. See MVS-related information for MVS considerations regarding the use of SVC 144.
Each of these ptrace requests consumes system resources and requires some amount of time to complete. The cumulative effect might be performance that is slower than expected.
The PT_CAPTURE request allows you to capture one or more virtual pages of storage in the debugged process into a buffer in your address space. After capturing storage in this manner, you have shared write access to the storage, and can access it directly by accessing the returned buffer. This allows you to bypass those ptrace requests that would normally be used to read or write storage in the debugged process. One use for the PT_CAPTURE request could be to capture the entire debugged program load module. Then, using the same example of stepping over a breakpoint instruction, you could eliminate all but the PT_WRITE_GPR and PT_CONTINUE requests by directly placing SVC 144 instructions and restoring program instructions in the captured buffer. Any storage that is accessible by the debugged program can be captured in this manner.
Storage that is captured using the PT_CAPTURE request is always on a 4K page boundary, and the minimum amount of storage captured is one 4K page. You are responsible for determining the correct offset of the desired storage in the captured buffer. For example, if the address you want to capture is 3A094BE8, the PT_CAPTURE request captures the entire page starting at 3A094000. If the service returns a capture buffer address of 35081000, the start of the desired storage in this buffer is 35081BE8.
The PT_UNCAPTURE request is used to free a specific buffer or all captured buffers. Freeing the buffer by using this request severs the capture relationship between the captured storage and the local buffer. To free a specific buffer, pass the buffer address on the ptrace request. To free all buffers, pass a 0 buffer address.
To cause a stopped, debugged process to resume running, you use the ptrace PT_CONTINUE service request. The request specifies whether running is to continue from where it was stopped, or at another instruction counter address. It also specifies whether the process is to continue as though no signal, or a specified signal, had just been received.
These two functions of the PT_CONTINUE request can be used to accomplish several debugging objectives. For instance, if the debugged program was stopped by a particular signal (for instance, SIGINT), the debugger can indicate that the program can continue normally, and can continue as though a SIGINT had just arrived. In effect, this allows the program to continue as though it had not been interrupted by the ptrace service. The debugger could also choose to ignore the signal that stopped the process (again assume a SIGINT), by specifying PT_CONTINUE without a signal. This allows the program to resume running, but the original SIGINT is discarded before it is delivered to the debugged program.
When a debugger finishes debugging a program, it uses the PT_DETACH request to take the process out of debugging mode and allow it to continue. A signal can be supplied on this request, as it is with the PT_CONTINUE request.
When a process is continued using these ptrace service requests, all signals that are pending on the focus thread, and all signals that are pending on the process (other than the ones supplied on the PT_CONTINUE or PT_DETACH service request, or SIGKILL), are discarded.
For example, if the process was in a stopped state, and a SIGCONT is supplied on the request, the process is taken out of the stopped state. However, if it was also waiting for the arrival of a signal, it still waits after the ptrace service request. Likewise, a signal whose action is to wake up processes that are waiting for a signal does so if the debugged process was waiting for a signal. If the process was in a stopped state, however, it remains in a stopped state after the ptrace service request has been processed. For more information about signal processing, see z/OS UNIX System Services Messages and Codes.
To end a stopped, debugged process, you can use the ptrace PT_KILL service request. This causes the process to end as though it had received a SIGKILL signal. You can also use the PT_CONTINUE request to continue with a signal whose action is to end the process, although this has the effect of ending the process with the specified signal instead of with a SIGKILL.
Multiprocess debugging mode allows a debugger to control more than one process. The debugger uses the ptrace PT_MULTI service request to turn multiprocess mode on or off for a target process.
When multiprocess mode is in effect, the behavior of the exec, fork, attach_exec, attach_execmvs, and spawn services is modified. For the exec service, the only change is that the Status_field parameter on the wait service issued by the debugger indicates that the process stopped for the exec service, instead of that it was stopped by the SIGTRAP signal.
For the fork service, the Status_field parameter on the debugger wait service indicates that the process stopped for the fork call. In addition, the fork service causes both the parent and the new child process to stop, and the debugger gets status for both processes with the wait service. The debugger should issue the wait service until it receives status for both the parent and child processes. This is different from multiprocess mode's not being in effect; in this case neither the parent nor child process stops because of the fork service, and the debugger is not made aware of the fork event at all.
For the attach_exec and attach_execmvs services, the Status_field parameter on the debugger wait service indicates that the process stopped for a local fork. In addition, these services cause both the parent and the new child process to stop, and the debugger gets status for both processes with the wait service. The debugger should issue the wait service until it receives status for both the parent and child processes. This is different from multiprocess mode's not being in effect; in this case, neither the parent nor child process stops because of these services, and the debugger is not made aware of the local fork event at all. After the notification of the local fork event, the attach_exec service loads the executable program into storage and causes the Status_field parameter on the wait service issued by the debugger to indicate that the process stopped for the exec service, instead of that it was stopped by the SIGTRAP signal.
For the spawn service, the effects are a combination of those described for fork and attach_exec. The parent presents status like that for a fork call (the debugger wait Status_field indicates that the process stopped for a fork). The child presents status like that for attach_exec (the debugger wait Status_field indicates that the process stopped for a local fork).
The PT_READ_U request is used with the user area for a target process. The user area is a collection of control information. It is not necessarily a contiguous storage area, and it is not readily accessible by an end user except via the PT_READ_U request.
Constant | Control information |
---|---|
PtUArea#MinSig–PtUArea#MaxSig | Signal catcher information for signal numbers 1 - 64 (the rest
of the range is reserved). Not all potential signal numbers are valid;
the valid signal numbers are defined in the BPXYSIGH macro. Signal
catcher information is one of the following (the constants for signal
default and ignore actions are defined in the BPXYSIGH macro):
|
PtUArea#IntCode | Program interrupt code, in the following format:
|
PtUArea#AbendCC | Abend completion code, in the following format:
|
PtUArea#AbendRC | Abend reason code |
PtUArea#SigCode | Signal code, in the following format:
|
PtUArea#ILC | Instruction length code, in the following format:
|
The PT_READ_U request can therefore be used to obtain additional information about signals; or when a debugger is notified that a debugged process stopped with a SIGILL, SIGSEGV, SIGFPE, or SIGABND signal.
A process that is running with any of these conditions ends abnormally if it attempts to use the ptrace service to notify the debugger of a ptrace service event.
For an example using this callable service, see BPX1PTR (ptrace) example.