ptrace (BPX1PTR, BPX4PTR) — Control another process for debugging

Function

The ptrace callable service provides information about another process and controls its running. Use this service in debugger programs to do breakpoint debugging.

Requirements

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.

Format

The syntax format is as follows:

AMODE 64 callers use BPX4PTR with the same parameters. The Address, Data, and Buffer parameters are doublewords.

Parameters

Request
Supplied parameter
Type:
Integer
Length:
Fullword

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.

Process
Supplied parameter
Type:
Integer
Length:
Fullword

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.

Address
Supplied parameter
Type:
Address or Integer
Length:
Fullword (doubleword)

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.

Data
Supplied parameter
Type:
Integer
Length:
Fullword (doubleword)

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.

Buffer
Supplied parameter
Type:
Address or Integer
Length:
Fullword (doubleword)

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.

Return_value
Returned parameter
Type:
Integer
Length:
Fullword

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
Returned parameter
Type:
Integer
Length:
Fullword
The name of a fullword in which the ptrace service stores the return code. The ptrace service always returns Return_code, even if Return_value is not -1. A Return_code of 0 is returned for successful completion. For a complete list of possible return code values, see z/OS UNIX System Services Messages and Codes. For a mapping of these values to the various requests, see Table 5. The ptrace service can return one of the following values in the Return_code parameter:
Table 1. Return codes for ptrace
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 length is larger than the maximum defined length. The maximum defined length is defined in the BPXYPTRC macro.
  • The length of the area that is to contain the results of a PT_LDINFO, PT_EXPLAIN, or PT_THREAD_INFO request (the return information buffer) is too small to contain all the required information. For PT_LDINFO and PT_EXPLAIN, increase the length up to the maximum defined length and reissue the request. For PT_THREAD_INFO, the required buffer length is returned. Reissue the request, using this returned buffer length. See Table 4 for more information (the required length is returned to the Destination Address).
  • For the PT_CAPTURE request, the input address that is to be captured is not on a page boundary (4K).
  • For the PT_UNCAPTURE request, the input captured buffer address is not an address that was previously returned from a successful PT_CAPTURE request.
  • For the PT_BLOCKEDREQ request, some of the requests might not have completed successfully. The Reason_code is set to JRPtSomeBlkedFailed. Check the PtBRStatus field of the PtBRInfo block for each blocked request to determine which have failed.

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 caller is not running with PSW key 8.
  • An incorrect Request was specified.
  • For a PT_TRACE_ME or PT_ATTACH request, the target process is already being debugged. For a PT_REATTACH or PT_REATTACH2 request, the target process is not already being debugged.
  • For a PT_DETACH, PT_CONTINUE or PT_THREAD_SIGNAL request, the signal number that was supplied in the Data parameter is not a valid signal number.
  • An address in the target process is not valid.
  • A register number for a PT_READ_GPR, PT_WRITE_GPR, PT_READ_FPR, PT_WRITE_FPR, PT_READ_VR, or PT_WRITE_VR request is not defined. The register numbers are defined in the BPXYPTRC macro.
  • An attempt was made to store into a control register using the PT_WRITE_GPR request.
  • An attempt was made to store into the left half of the PSW using the PT_WRITE_GPR request.
  • The user area offset that was supplied with the PT_READ_U request is incorrect.
  • For the PT_TRACE_ME request, the parent of the debugged process (that is, the debugger) has ended.
  • For the PT_REATTACH or PT_REATTACH2 request, the original debugger has ended.
  • For the PT_THREAD_WRITE_FOCUS, PT_THREAD_HOLD, PT_THREAD_MODIFY and PT_THREAD_SIGNAL requests, the thread ID that was supplied is not valid.
  • For the PT_EXPLAIN request, an extended ptrace event is not in progress.
  • For the PT_EVENTS request, an attempt was made to add more extended events than the maximum number of events that was specified on the PT_EVENTS request.
  • The request is not supported while it is stopped for a local fork child, or for an extended event.
  • For the PT_CAPTURE request, the target process is running in a TSO address space.

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:
  • For the PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests, the target process is restricted from being debugged.
    Note: For PT_REATTACH or PT_REATTACH2, it is more likely that EIO will be returned, because the target process is not already being debugged. However, in the unlikely event that a restricted process successfully issues a PT_TRACE_ME request, a PT_REATTACH or PT_REATTACH2 could return EPERM.
    If either of the following is true, the target process is restricted:
    • The target process is a system address space. For more information about system address spaces, see MVS-related information.
    • The target process is the INIT process, indicated by a process ID (PID) value of 1.
  • For the PT_READ_xxx, PT_WRITE_xxx, PT_CONTINUE (to continue at another address), PT_REGSET and PT_LDINFO requests, the target process is currently running in supervisor state.

The following reason codes can accompany the return code: JRPtRestrictedProcess, JRPtEdIsAuthorized.

ESRCH The request was not accepted, for one of the following reasons:
  • For all requests other than PT_TRACE_ME, PT_ATTACH, PT_REATTACH, PT_REATTACH2, PT_EXTENDED_EVENT, and PT_RECOVER, the target process is not being debugged.
  • For all requests other than PT_TRACE_ME, PT_ATTACH, PT_REATTACH, PT_REATTACH2, PT_EXTENDED_EVENT, and PT_RECOVER, the target process is not stopped for a ptrace service event.
  • For all requests other than PT_TRACE_ME, PT_EXTENDED_EVENT, and PT_RECOVER, the target process ID is incorrect.
  • For the PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests, the target debugged process is the same as the debugger process.
  • For the PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests, the target debugged process is the parent of the debugger process.

The following reason codes can accompany the return code: JRPtDbdEqualsDbr, JRPtDbdPidNotFound, JRPtProcessNotPtraced, JRPtProcessNotStopped, JRPtDbrParentEqualsDbd.

Reason_code
Returned parameter
Type:
Integer
Length:
Fullword
The name of a fullword in which the ptrace service stores the reason code. The ptrace service always returns Reason_code, even if Return_value is not -1. A Reason_code of 0 is returned for successful completion. The reason code for EMVSSAF2ERR contains the RACF® return and reason codes, respectively, in the two low-order bytes. For a more detailed description of the RACF ptrace Authority Check service return and reason code values, see Table 2:
Table 2. RACF return and reason codes for the ptrace authority check service
Return code Reason code Explanation
8 4 The caller is not authorized to attach to the target process
8 12 Internal error during RACF processing

Constant options for the ptrace request parameter

Table 3 shows the constant options that you can select for the Request parameter. See BPXYPTRC — Map parameters for ptrace for the constant definitions.

Table 3. Constant options for the ptrace request parameter
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.
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.

Parameter attributes for request options

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:

Table 4. Parameter attributes for request options
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
Buffer Address
The name of a fullword that contains an address in the caller's process where either:
  • The results of the request are to be placed
  • The source information for the request is to be obtained
The size of the buffer is specified with the Length parameter.
Capture Address
The name of a fullword that contains an address in the target process that is to be captured into a buffer in the caller's address space. This address must be on a page boundary (4K).
Capture Buffer
The name of a fullword that contains an address in the caller's process that represents a captured storage buffer. This address must have been previously returned to the caller on a PT_CAPTURE request.
Capture Length
The name of a fullword that contains the length of the storage that is to be captured. There is no need to round this length up to the size of a page.
Continue Address
The name of a fullword that contains an address in the target process from which the debugged program is to continue running. The address must include the addressing mode (AMODE) as the high-order bit. A high-order bit of 0 indicates a 24-bit AMODE; a high-order bit of 1 indicates a 31-bit AMODE.

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.

Debugged Address
The name of a fullword that contains an address in the target process.
Destination Address
The name of a fullword that contains an address in the caller's process at which the results of the request are to be placed. The size of the destination area is defined by the request type.
Extended Event ID
The name of a fullword that contains an extended event ID.
Integer Value
The name of a fullword that contains the value that is to be placed at the Debugged Address location.
GIParm Address
The name of a fullword that contains the address of the generic interface parameters. For more information, see Handling extended events in a debugged process.
Length
The name of a fullword that contains the length that is associated with the Buffer Address. The maximum length value is defined in the BPXYPTRC macro, except for the PT_THREAD_INFO request.
Maximum Events
The name of a fullword that contains the maximum number of extended events that will be added using the PT_EVENTS request. This is required only for the first issuance of PT_EVENTS, but it can be specified on all issuances.
PCParm Address
The name of a fullword that contains the address of the program check parameters. For more information, see Handling a program check or abend in a debugged process.
Register Number
The name of a fullword that contains a defined register number. The register numbers are defined in the BPXYPTRC macro.
Register Value
The name of a fullword that contains the register value that is to be placed in the Register Number in the target process.
Signal Number
The name of a fullword that contains the signal number that is to be sent to the target debugged process or thread. The signal numbers are defined in the BPXYSIGH macro.
Source Address
The name of a fullword that contains an address in the caller's process where the source information for the request is to be obtained. The size of the source area is defined by the request type.
Target Offset
The name of a fullword that contains an offset into the user area in the target process. The user area contains control information. For a description of the user area, see User area description.
Thread ID Address
The name of a fullword that contains an address in the caller's process where either:
  • The target thread ID is to be placed
  • The target thread ID is to be obtained

The length of the thread ID is 8 bytes.

Return values and return codes for request options

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.

Table 5. Return values and return codes for request options
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

Starting a process in debugging mode

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.

Attaching to a process for debugging

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.

This is required because of the restricted nature of the local fork child environment. Normally, after a reattach to a fork child, the debugger can continue issuing ptrace requests, because the child is a copy of the parent and is already stopped for a ptrace event. However, a local fork child is not a copy of the parent, and in fact most ptrace requests fail if issued to a local fork child, because the target program that is specified on the attach_exec or attach_execmvs service has not yet been loaded for execution. The alternate processing required by the debugger for this environment is to issue a PT_CONTINUE request, followed by a wait(). This causes the local fork child to continue until the next ptrace event, which will be an exec event for the attach_exec service. At this point, the target program is loaded, and the debugger can continue issuing ptrace requests in this valid environment.
Note: ptrace has no way to know whether the target of the PT_REATTACH2 is the local fork parent or the local fork child. It is the debugger's responsibility to issue the request for the local fork child only. The result of issuing this request for the local fork parent is that control of the parent is lost; it will continue running until the next ptrace event.

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.

Receiving notification of events in a debugged process

When a process has been placed into debugging mode by the PT_TRACE_ME, PT_ATTACH, PT_REATTACH, or PT_REATTACH2 request, certain events in the debugged process cause the process to be placed into a stopped state and the debugger to be notified. The debugger must wait for these events by using the wait service. The following are the events of interest:
  • A signal is received. The Status_field parameter on the wait service issued by the debugger contains the signal number.
  • An exec service is issued. The Status_field parameter on the wait service issued by the debugger either contains the SIGTRAP signal number, if multiprocess debugging is not in effect; or indicates that the process stopped for an exec (WastStopFlagExec), if multiprocess debugging is in effect. For information about multiprocess debugging, see Multiprocess debugging mode. Also see BPXYWAST — Map the wait status word for a description of the Wast values.
  • A fork service is issued and multiprocess debugging mode is in effect. The Status_field parameter on the wait service issued by the debugger indicates that the process stopped for a fork (WastStopFlagFork).
  • An attach_exec or attach_execmvs service call is issued and multiprocess debugging mode is in effect. The Status_field parameter on the wait service issued by the debugger indicates that the process stopped for a local fork (WastStopFlagLocalFork).
  • A spawn service call is issued and multiprocess debugging mode is in effect. The Status_field parameter on the wait service issued by the debugger indicates that the process stopped for a fork (WastStopFlagFork) for the spawn parent, and for a local fork (WastStopFlagLocalFork) for the spawn child.
  • An SVC 144 instruction is run. SVC 144 is used as a breakpoint by debugger programs. The debugger uses the ptrace service to store the SVC 144 instructions into the program at the appropriate breakpoints. The Status_field parameter on the wait service issued by the debugger contains the SIGTRAP signal number.
  • A program check or abnormal end is encountered. The debugger is notified only if the program check or abnormal end causes the ptrace service to be called with a PT_RECOVER request. This is normally true for programs that detect the error, and that can provide the proper interface to the PT_RECOVER request. An ESPIE routine is an example of this. The Status_field parameter on the wait service issued by the debugger contains the appropriate signal number. For more information, see Handling a program check or abend in a debugged process.
  • An extended event occurs and a generic debugger interface module issues the ptrace PT_EXTENDED_EVENT request. Extended events are enabled by using the PT_EVENTS service request. Only those events thus enabled cause a ptrace extended event to occur. Handling extended events in a debugged process provides more information about the generic debugger interface. The debugger must use the PT_EXPLAIN request to obtain additional information about the extended event. The Status_field parameter on the wait service issued by the debugger indicates that the process stopped for an extended event (WastStopFlagExtended).
  • A loadhfs service is issued. The Status_field parameter on the wait service issued by the debugger indicates that the process stopped because of a file system module load (WastStopFlagLoad).
  • A deletehfs service is issued. The Status_field parameter on the wait service issued by the debugger indicates that the process stopped because of a file system module delete (WastStopFlagDelete).

Table 6 summarizes the events and the corresponding status reported to the debugger from the wait call:

Table 6. Corresponding ptrace event and status that is reported to the debugger
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.

Working with threads in a debugged process

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.

Signals can be sent to the debugged process using the PT_CONTINUE and PT_DETACH requests, as explained Resuming or detaching from a debugged process.. These signals are always directed at the current focus thread. The PT_THREAD_SIGNAL service request provides a means to send signals to individual threads that are not in a dead state. The signal that is specified on this request is generated for the target thread, but it is not delivered until the process is continued. A debugger can use this request to requeue signals that were pending on a thread when a ptrace event occurred. Normally, all signals (except those specified on PT_CONTINUE or PT_DETACH) that are pending on the focus thread are discarded when the process is continued. Using the signal information that is returned on the PT_THREAD_INFO request, the debugger could regenerate all pending signals by using the PT_THREAD_SIGNAL request. This is useful when changing thread focus; otherwise, any signals that were pending on nonfocus threads when the original ptrace event occurred might be lost.
Note: To ensure that pending signal information for the focus thread is not lost (because the signals were discarded), the PT_THREAD_INFO request should be the first ptrace request that is issued when the debugger gets notified of a ptrace service event.
Finally, the PT_THREAD_MODIFY service request allows the debugger to modify individual thread kernel information for a thread that is in a dead state. The input to this request is a single thread info array entry, as returned by the PT_THREAD_INFO request, modified as necessary with the required changes. The following information is allowed to be changed:
  • Thread exit status for threads in a dead state (PtPtExitStatus)

Determining modules loaded in a debugged process

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.

Handling a program check or abend in a debugged process

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.

However, if the process is being debugged, the ptrace service stops the process by sending an appropriate signal to the focus thread. The debugger (not the application) sets this signal with the Status_field parameter on the wait call. These are the possible signals that are used for program checks:
SIGILL
Unpermitted operation, defined as one of the following:
  • Operation exception
  • Privileged operation exception
  • Execute exception
  • Specification exception
SIGSEGV
Addressing error, defined as one of the following:
  • Protection exception
  • Addressing exception
SIGFPE
Arithmetic error, defined as one of the following:
  • Data exception
  • Fixed-point overflow exception
  • Fixed-point divide exception
  • Decimal overflow exception
  • Decimal divide exception
  • Exponent overflow exception
  • Exponent underflow exception
  • Significance exception
  • Floating-point divide exception
The interface to the PT_RECOVER request is the program check parameters structure, which is pointed to from the Address parameter. This structure contains pointers to environment information from the time of the program check or abnormal end. It also contains flags and information that is returned from the ptrace service. The program check parameters structure is defined in the BPXYPTRC macro. The ptrace service distinguishes between program checks and other abnormal ends. The presence of an abend code causes the interrupt to be interpreted as a SIGABND signal. The presence of an interrupt code without an abend code causes it to be interpreted as SIGILL, SIGSEGV, or SIGFPE, as appropriate. The following shows the information that must be present in the program check parameters structure on input to PT_RECOVER:
  1. In all cases the following must be set:
    • PtPICRegisters = address of registers at time of error (0 - 15)
    • PtPICPSW = address of PSW at time of error
    • PtPICFlags = 0 (except PtPICILCExists if PtPICILC is set)
  2. For program checks, the following must be set:
    • PtPICIntCode = program interrupt code
    • PtPICAbendCode = 0
  3. For program checks, the following are optional:
    • PtPICILC = instruction length code
    • PtPICILCExists = flag set to 1 to indicate PtPICILC is valid
  4. For non-program check abnormal ends, the following must be set:
    • PtPICAbendCode = abend code
    • PtPICAbendReason = reason code
    • PtPICILCExists = flag set to 0 to indicate PtPICILC is not used
  5. For any program check that is not specified in the foregoing list, SIGFPE is used. For abnormal ends (abends) SIGABND is used.

    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.

    When the registers or the PSW are changed by the debugger, the appropriate flag in the program check parameters, as defined in the BPXYPTRC macro, is set to indicate this. Conversely, if the registers or PSW are not changed, the flag is not set. Thus the caller can test these flags to determine if changes were made to the registers or the PSW, and therefore need to be reflected in the program environment before the program resumes running. See MVS-related information.
    Note: The PT_RECOVER request, along with PT_TRACE_ME and PT_EXTENDED_EVENT, is issued from the process that is to be debugged. All other ptrace service requests are issued from the debugger.

Handling extended events in a debugged process

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.

To allow events that are invoked in this manner to be used by a debugger using ptrace, z/OS UNIX ships a sample CEEEVDBG module. This module "glues" the Language Environment Interactive Debug Event Handler interface to the debugger, using the ptrace PT_EXTENDED_EVENT request to create an extended event. However, any product can choose to use the PT_EXTENDED_EVENT request to create extended events in this manner; CEEEVDBG is just an example of the proper usage. The relationship between the PT_EXTENDED_EVENT, PT_EVENTS and PT_EXPLAIN requests can best be illustrated with a usage scenario:
  1. The Language Environment Interactive Debug Event Handler interface is enabled for the program to be debugged. Refer to z/OS Language Environment Debugging Guide for the steps that are required to accomplish this, as this is outside the scope of ptrace.
  2. The sample CEEEVDBG module is installed so that Language Environment can load it. More information is provided in MVS-related information.
  3. The debugger issues one or more PT_EVENTS requests to establish the set of extended events for which it has an interest. This should normally be done just after the target program has been placed into debugging mode, during debugger initialization regarding the debugged program. There are, however, no restrictions on modifying the list of extended events any time the debugged program is stopped for an event.
  4. The program is allowed to run. When Language Environment encounters certain events (for example, a mutex initialization, lock, or unlock), it invokes CEEEVDBG with the appropriate event code.
  5. CEEEVDBG collects certain information about the event and issues the PT_EXTENDED_EVENT request to invoke ptrace. The information that is collected consists of the event code and registers 1, 12 and 13 at input to CEEEVDBG. Register 1 contains the address of the parameter list that contains the event code and associated information. Registers 12 and 13 contain the addresses of Language Environment control blocks that the debugger can use to gather additional information. The extended event information structure is defined in the BPXYPTRC macro.
  6. The PT_EXTENDED_EVENT request filters the input event code with the set of events established with the PT_EVENTS requests. If the input event code is found in the list, an Extended Event is initiated. This causes the debugged program to stop and the debugger to be notified. The corresponding wait() status reported to the debugger is WastStopFlagExtended.
  7. The debugger reacts to the unique wait() status by issuing the PT_EXPLAIN request. This request returns the information collected by the PT_EXTENDED_EVENT request to the debugger.
  8. Because the information is in the form of addresses, the debugger must issue PT_READ_D or PT_READ_BLOCK requests to obtain the associated extended event information.

Manipulating data in a debugged process

You can use the ptrace service to look at the following types of data in the debugged process; some might be altered.
  1. General or machine control registers. This includes general-purpose registers (GPRs), floating-point registers (FPRs), vector registers (VR), control registers (CRs), and the program status word (PSW). Control registers can only be looked at, never modified. Control registers contain system information, and their content is not necessarily related to the debugged process. The value of some of the control registers might change from one call of PTRACE to the next, even when the debugged process is stopped across both calls. The entire PSW can be looked at, but only the rightmost 4 bytes (the instruction counter and addressing mode) can be changed. The PT_READ_GPR and PT_WRITE_GPR requests are used for all registers except the FPRs, and the interface supports 4 bytes only. As a result, the PSW must be accessed with two ptrace service requests, each specifying the register number for the appropriate half of the PSW.

    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.

    Restriction: Only the second fullword of the PSW can be written into.

    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.

  2. User program storage. This takes two forms. The first is for fullword requests, which look at or modify a fullword of storage only. The PT_READ_I, PT_READ_D, PT_READ_U, PT_WRITE_I, and PT_WRITE_D requests are used to accomplish this. For MVS considerations, see MVS-related information. The user area request (PT_READ_U) operates on the user area. For more information, see User area description.

    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.

  3. Blocking requests. Most of the requests described here can be blocked into a single ptrace call by using the PT_BLOCKREQ request. This saves system resources when a large amount of information must be read or written. The PT_BLOCKREQ request can be used, for example, to read or write all the GPRs, all the FPRs, and several areas of user program storage on a single request. The PtBRInfo structure, defined in macro BPXYPTRC, defines the mechanism for blocking several requests into a single request.

Setting a breakpoint in a debugged process

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.

Note: It is the responsibility of the caller to save and restore the actual program instructions that are overlaid by inserted breakpoint SVCs. You can use ptrace services to accomplish this, but no implicit understanding or management of program instructions is done by the ptrace service.

Capturing storage in a debugged process.

When you use the standard ptrace requests previously discussed, you pay a performance penalty when you perform certain operations. For example, stepping over a breakpoint instruction while leaving the breakpoint in the program requires several ptrace requests, as in the following scenario:
  • PT_WRITE_I to restore the original instruction over the SVC 144
  • PT_READ_I to get the fullword following the restored instruction
  • PT_WRITE_I to insert a temporary SVC 144 after the restored instruction
  • PT_WRITE_GPR to back up the PSW to point to the restored instruction
  • PT_CONTINUE to execute the restored instruction and hit the temporary breakpoint
  • PT_WRITE_I to restore the temporarily overlaid instruction
  • PT_WRITE_I to reinsert the SVC 144 at its original location
  • PT_WRITE_GPR to back up the PSW to point to the restored temporary instruction
  • PT_CONTINUE to resume running until the next event

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.

Resuming or detaching from a debugged process.

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.

When a debugged process is stopped because of a signal, or is waiting for a signal to arrive when the PT_CONTINUE or PT_DETACH request is issued, there are special considerations:
  • If no signal is supplied on the ptrace service request, the process continues running immediately. If it was in a stopped state, it behaves as if a SIGCONT had just arrived. If it was waiting for a signal, it behaves as if a signal had just arrived.
  • If a signal is supplied on the ptrace service request, that signal takes whatever action it normally would with respect to the state of the debugged process.

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.

Ending a debugged process

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

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).

User area description

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.

To access the user area, an offset, as opposed to an absolute address, must be supplied on the PT_READ_U request. Each unit of control information is a fullword, and the offsets represent each multiple of 4 bytes. The offsets begin with 1 and progress by 1. Table 7 shows the offsets and the associated control information that are defined in the BPXYPTRC macro (see BPXYPTRC — Map parameters for ptrace):
Table 7. Offsets and associate information that are defined in BPXYPTRC
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):
  • SIG_DFL#: Take default action for this signal
  • SIG_IGN#: Ignore this signal
  • Address: Address of the signal catcher function
PtUArea#IntCode Program interrupt code, in the following format:
  • Bytes 0 and 1: unused
  • Bytes 2 and 3: program interrupt code in hexadecimal
PtUArea#AbendCC Abend completion code, in the following format:
  • Byte 0: flags
  • Bytes 1–3: system completion code (first 12 bits) and user completion code (second 12 bits)
PtUArea#AbendRC Abend reason code
PtUArea#SigCode Signal code, in the following format:
  • Bytes 0 and 1: unused
  • Bytes 2 and 3: signal code in hex
PtUArea#ILC Instruction length code, in the following format:
  • Bytes 0–2: unused
  • Byte 3: instruction length code

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.

Characteristics and restrictions

The following restrictions apply to the use of the ptrace service:
  1. The ptrace service is supported from programs that are running in PSW key 8 mode only. Calls to the ptrace service that are made from debugger programs (authorized or problem state) with other than key 8 are rejected with an error code.
  2. A process that is being debugged must not be running if any of the following environmental conditions are true:
    • It is running in access register (AR) mode.
    • It is running in supervisor PSW state.
    • It is running with a PSW key not equal to 8.
    • It is running with APF authorization, and the debugger process does not have read permission to the BPX.DEBUG resource in the FACILITY class.
    • It is running with the security product function called Program Access to Data Support (PADS) activated.

    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.

  3. A SIGKILL signal that is sent to a process that is being debugged by the ptrace service cannot be trapped. When a SIGKILL signal ends a process, the ptrace service is not given a chance to intervene.
    Note: SIGKILL is delivered to the target process according to normal signal delivery rules. If the target process is stopped, but is not waiting for signals (for example, if it is stopped for a ptrace service event), the SIGKILL remains pending until the process resumes (using the same example, when a PT_CONTINUE, PT_DETACH, or PT_KILL ends the ptrace service event).
  4. The PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests cannot be issued with a target process that is a system address space (see MVS-related information). If this attempt is made, the EPERM error is returned in the Return_code parameter.
  5. The PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests cannot be issued with a target process that is the INIT process (with a process identifier equal to 1). If this attempt is made, the EPERM error is returned in the Return_code parameter.
  6. The PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests cannot be issued with a target process that is the parent of the calling process. If this attempt is made, the ESRCH error is returned in the Return_code parameter.
  7. The PT_ATTACH, PT_REATTACH, and PT_REATTACH2 requests cannot be issued with a target process that uses the setuid service to set the uid to 0, unless the process is also running with superuser equal to daemon authority (in other words, is running without an active BPX.DAEMON resource profile in the FACILITY class). If this attempt is made, the EPERM error is returned in the Return_code parameter.
  8. The debugger cannot use multiple threads within a single process to debug multiple target processes. If multiprocess debugging is desired, either a single thread debugger process must be associated with all debugged processes, or the debugger must use multiple processes, where the association with debugged processes is on a one-to-one basis.
  9. The debugger should not have a signal catcher for the SIGCHLD signal. The ptrace service uses the SIGCHLD signal for internal communication, and the use of a catcher by the debugger would interfere with this communication. The most visible result of using a SIGCHLD catcher would be EINTR errors returned for most ptrace service requests, although other unpredictable results could also occur.
  10. To ensure that pending signal information for the focus thread is not lost (because the signals were discarded), the PT_THREAD_INFO request should be the first ptrace request that is issued when the debugger gets notified of a ptrace service event.
  11. The following requests are not supported while a debugged process is stopped for a local fork child event:
    • PT_READ_I
    • PT_READ_D
    • PT_READ_BLOCK
    • PT_READ_GPR
    • PT_READ_GPRH
    • PT_READ_FPR
    • PT_WRITE_I
    • PT_WRITE_D
    • PT_WRITE_BLOCK
    • PT_WRITE_GPR
    • PT_WRITE_GPRH
    • PT_WRITE_FPR
    • PT_REGHSET
    • PT_REGSET
    • PT_CONTINUE to continue at a specified address
    • PT_READ_VR
    • PT_WRITE_VR
  12. The following requests are not supported while a debugged process is stopped for an extended event:
    • PT_READ_GPR
    • PT_READ_GPRH
    • PT_READ_FPR
    • PT_WRITE_GPR
    • PT_WRITE_GPRH
    • PT_WRITE_FPR
    • PT_REGHSET
    • PT_REGSET
    • PT_CONTINUE to continue at a specified address
    • PT_READ_VR
    • PT_WRITE_VR
  13. If the debugger is running in a multi-thread process, then the SIGCHLD signal must be blocked on all threads except the one issuing the BPX1PTR call.

Examples

For an example using this callable service, see BPX1PTR (ptrace) example.

MVS-related information

  1. As a result of the PT_LDINFO request, the ptrace service invokes the Contents Supervisor CSVINFO service. CSVINFO returns information about load modules in the debugged process based on CSV control blocks. This information is then returned to the caller of the PT_LDINFO request. CSVINFO uses the MVS macros ATTACH, LINK or XCTL; or the exec or loadhfs service to return information about all modules brought into storage by any task in the process.
  2. PT_READ_GPR requests that read the machine control registers (CRs) can return CR information that is not consistent with the user program that is being debugged. This is because the ptrace service reads the actual hardware registers that probably have changed because of internal PC invocations.
  3. No distinction is made between the instruction area (_I) or data area (_D) for the PT_READ_I, PT_READ_D, PT_WRITE_I, and PT_WRITE_D requests. These are all treated as user storage requests.
  4. A debugger cannot set breakpoints in programs that are loaded into read-only storage (for example subpool 252 or LPA). Users of debugger programs that use ptrace must be aware of the storage location of their programs, and, if necessary, take appropriate steps to ensure that the programs are loaded into read/write storage (for example, subpool 251).
  5. The PT_RECOVER request can be issued by ESPIE and ESTAE routines that capture program checks in user programs. The main requirement is that any registers or PSW values that are changed by the debugger after it recognizes the program check event be restored before the user program resumes running. Also, if a signal is sent to the debugged program by the user recovery routine, it must be sent outside of the user recovery routine (ESPIE or ESTAE). This ensures that signal delivery operates in the correct environment.
  6. SVC 144 instructions can be inserted only into storage key 8 user programs. You cannot use SVC 144 instructions to do breakpoint debugging of system (key 0) routines.
    The SVC 144 routine has the following characteristics:
    • SVC 144 is a type-3 SVC.
    • The user program registers and PSW that are saved by the SVC 144 routine are changed if requested by PT_WRITE_GPR requests.
    • Any modification that is made to register 14 with a PT_WRITE_GPR request is lost. This is because the SVC 144 routine uses register 14 to exit.
    • If the process under which the SVC 144 routine runs is not in ptrace mode (started with a PT_TRACE_ME, PT_ATTACH, PT_REATTACH or PT_REATTACH2 request), the routine abends the caller.
    • If the SVC 144 routine is called while the process is in access register mode, supervisor state, or any key other than 8, the routine abends the caller. In addition, APF-authorized invocation is not allowed unless the debugger has read permission to the BPX.DEBUG resource in the FACILITY class.
  7. MVS system address spaces cannot be debugged with the ptrace service. A system address space is identified by one of the following:
    • A command scheduling control block (CSCB) does not exist. The master address space is an example of an address space with no CSCB.
    • The CSCB identifies the address space as a system address space.
  8. The sample CEEEVDBG module must be installed as follows:
    • The sample CEEEVDBG module is in the form of source code that is written in basic assembler language. This module must be assembled with the following Language Environment macros made available to the assembler: CEECAA, CEEDSA, CEEENTRY, CEEPPA.
    • The object deck must be link-edited with the object deck for the ptrace system call stub.
    • The load module must be placed into a load library that is accessible by Language Environment.