dg_xtrace(2) DG/UX R4.11MU05 dg_xtrace(2)
NAME
dgxtrace - extended process trace
SYNOPSIS
#include <sys/dgxtrace.h>
int dgxtrace (request, data)
int request;
union dgxtraceu * data;
where:
request Process trace command of the form DGXTname, where name is
a unique suffix indicating the action to be taken.
data Pointer to union used for completing the process trace
command.
DESCRIPTION
dgxtrace lets a process (debugger process) control the execution of
another process (target process). Its primary use is to implement
breakpoint debugging; see mxdb(1) and dbx(1). It is an extended
version of ptrace that has been added to remedy two of the major
shortcomings of ptrace:
· the mandatory parent/child relationship between the tracing-
process and the process-being-traced, and
· the very small (32-bit) interface between the two processes.
Since the relationship between the two processes is no longer
mandated to be parent/child, some terms defining this new
relationship are needed so that discussion of their interaction is
possible. The process controlling the tracing of another process
will be referred to as the "controlling process" or "controller."
The process being traced will be referred to as the "target process"
or "target."
Tracing Relationships
Three valid tracing relationships exist between the controlling and
target processes:
· the controller is the PARENT of the target,
· the controller is the CHILD of the target, or
· the controller is NOT RELATED to the target (and is not the
target itself).
Some restrictions exist concerning the specifics of the tracing
relationship. In general, a target can become a controller, but a
controller cannot become a target. This avoids a cycle in the
controller-target relationship which could result in a deadlock
condition. A controller can trace multiple targets, but when the
controller terminates, all of its targets are sent SIGKILL. Finally,
if a controller (that is not a target) is the child of a process
being traced, then job control stop signals sent to the controller
will be ignored. This restriction is necessary because the parent
process is usually responsible for any stopped children (which is
impossible in this scenario).
In all configurations, the target process behaves normally until it
encounters a signal (see signal(2) for the list) or until it exits;
it then stops for tracing and its controller is notified via
dgxtrace using the request XT_WAIT_FOR_TARGET (defined below). (A
signal that is blocked does not cause the process to stop for tracing
until the signal is unblocked. If a job control stop signal is held
because the target process has performed vfork(2) but not exec(2) or
exit(3C), such a signal does not cause the process to stop for
tracing until the process has performed exec or exit.)
When the target is stopped, its controller can examine and modify its
address space using dgxtrace. Also, the controller can cause the
target either to terminate or continue, with the possibility of
ignoring the signal that caused it to stop.
In the first tracing relationship, the sequence of events required to
trace a process is as follows:
1. The target process is created by fork(2) or vfork(2).
2. The target process performs a dgxtrace operation with request
DG_XT_TRACE_ME.
3. The target's address space is changed by the exec(2)
operation. This causes the target to be stopped for tracing
before executing the first instruction of the new image as if
the signal SIGTRAP had occurred.
4. The controlling process waits for the target to stop for
tracing using dgxtrace with request DG_XT_WAIT_FOR_TARGET.
5. The controller may now cause the target to continue execution
using dgxtrace with request DG_XT_CONTINUE_TARGET.
In the second tracing relationship, the sequence of events required
to trace a process is as follows:
1. The controlling process is created by fork(2) or vfork(2).
2. The controlling process performs a dgxtrace operation with
request DG_XT_TRACE_PID specifying the parent process's
process ID. If the parent process is stopped due to a job
control signal (e.g., SIGSTOP) at the time DG_XT_TRACE_PID is
issued, DG_XT_TRACE_PID completes normally but tracing does
not actually occur until the parent process leaves the stopped
state (due to a signal that continues it or terminates it).
3. The controlling process waits for the target to stop for
tracing using dgxtrace with request DG_XT_WAIT_FOR_TARGET.
4. The controller may now cause the target to continue execution
using dgxtrace with request DG_XT_CONTINUE_TARGET.
In the third tracing relationship, the sequence of events required to
trace a process is as follows:
1. The controlling process performs a dgxtrace operation with
request DG_XT_TRACE_PID specifying the process ID of the
process to be traced. If the target is stopped due to a job
control signal (e.g., SIGSTOP) at the time DG_XT_TRACE_PID is
issued, DG_XT_TRACE_PID completes normally but tracing does
not actually occur until the target process leaves the stopped
state (due to a signal that continues it or terminates it).
2. The controlling process waits for the target to stop using
dgxtrace with request DG_XT_WAIT_FOR_TARGET.
3. The controller may now cause the target to continue execution
using dgxtrace with request DG_XT_CONTINUE_TARGET.
Tracing Requests and Macros
The request argument determines the precise action to be taken by
dgxtrace. For each request, a macro invocation of dgxtrace exists
that initializes the supplied dgxtraceu union pointer with the
appropriate values. Each macro name is of the form
DGXTRACEname([arguments])
where name is the same as the corresponding name in request.
arguments include various combinations of the following:
process-id The process ID of the target
targetaddr A byte address in the target process
controllingbuf A byte address in the controlling process
nchar The number of bytes to transfer between the two
processes
signal A signal to be sent when continuing a target
waitptr A pointer to an integer that receives information
about the traced process
targetspace Refer to the Target Spaces section below.
The xtraceunionptr argument is the only argument from the macro
interface which is passed to dgxtrace. The other argument values in
the interface are placed into the union at which xtraceunionptr
points. (See the actual dgxtrace interface above.)
Users should only access dgxtrace through the macro invocations.
The requests and their macros are as follows:
DG_XT_TRACE_ME
macro: DGXTRACETRACEME()
In the first configuration, the target process must issue this
request if it is to be traced by its controller (its parent).
This operation marks the target as being traced so that it
will be stopped for tracing upon receipt of a signal rather
than the state specified by its signal handler. A return
value of 0 is always returned with this request. [Unexpected
results may ensue if the controller (in this case, the parent)
does not expect to trace the target. For example, the
controller may not cause the target to continue after a
signal. Also, the target will be terminated if the controller
terminates.]
The other requests can be used only by the controller process.
DG_XT_TRACE_PID
macro: DGXTRACETRACEPID(process-id,
xtraceunionptr)
With this request, the controlling process issues a request to
establish a tracing relationship with a target process
(specified by process ID). This request will fail if:
· the effective-user-id of the controlling process does
not match the real-user-id and saved-user-id of the
target process, and the effective-group-id of the
controlling process does not match the real-group-id
and saved group ID of the target process, OR
· the user ID of the controlling process is not 0. If
the tracing relationship is successfully established,
it turns on the target's trace flag. This stipulates
that the target should stop for tracing upon receipt of
a signal rather than the state specified by its signal
handler. Note that this request does NOT cause a
signal to be sent to the target or otherwise cause the
target to stop. If the relationship cannot be
established, the request will fail, in which case the
error condition ESRCH is asserted. Under no
circumstances may a process trace itself!
DG_XT_UNTRACE_PID
macro: DGXTRACEUNTRACEPID(process-id,
targetaddr,
xtraceunionptr)
This request allows a controller to end the tracing session it
has with the process specified by process-id. By setting
targetaddr, the controller can specify the address that the
target continues from when it first begins executing again.
If targetaddr is set to 1, then the target will continue from
where it was when it stopped for tracing.
DG_XT_READ_TARGET
macro: DGXTRACEREADTARGET(process-id,
targetspace
targetaddr,
controllingbuf,
nchar,
xtraceunionptr)
With this request, the nchar bytes beginning at location
targetaddr in targetspace of the target's address space are
placed in the location controllingbuf in the controller's
address space. This request will fail when either targetaddr
or controllingbuf is not a valid byte address, nchar bytes
cannot be read or targetaddr is not a valid address in
targetspace, in which case the error condition EIO is
asserted. The request will also fail with EIO if the caller
is not the controller of the target or the target is not
stopped for tracing, though the stop need not have been
acknowledged with DG_XTRACE_WAIT_FOR_TARGET. Refer to the
Target Spaces section below.
DG_XT_WRITE_TARGET
macro: DGXTRACEWRITETARGET(process-id,
targetspace,
targetaddr,
controllingbuf,
nchar,
xtraceunionptr)
With this request, the nchar bytes beginning at location
controllingbuf in the controller's address space are placed
in the location targetaddr in targetspace of the target's
address space. This request will fail when either targetaddr
or controllingbuf is not a valid byte address, nchar bytes
cannot be written or targetaddr is not a valid address in
targetspace, in which case the error condition EIO is
asserted. The request will also fail with EIO if the caller
is not the controller of the target or the target is not
stopped for tracing, though the stop need not have been
acknowledged with DG_XTRACE_WAIT_FOR_TARGET. Refer to the
Target Spaces section below.
DG_XT_WAIT_FOR_TARGET
macro: DGXTRACEWAITFORTARGET(process-id-ptr,
waitptr,
options,
xtraceunionptr)
With this request, the controlling process waits for one of
its target processes. This request works like wait3(2) except
that it waits only for a traced process that has received a
signal (the wait3(2) WUNTRACED option is ignored). When one
of the controller's targets receives a signal, this function
returns the PID of that process and "acknowledges" that the
target has stopped so that subsequent calls to this function
will not return that same PID until the target has been
continued and it receives another signal. If none of the
targets has received a signal, then the caller is pended
unless the WNOHANG option is specified, in which case PID 0 is
returned and the caller is not pended. EIO is returned if the
caller is not the controller for any traced process.
Note: When a process terminates or an untraced process
receives one of the job control stop signals, the status is
always reported via wait3(2) performed by the parent, never
via DG_XTRACE_WAIT_FOR_TARGET. When a traced process stops
for tracing, the status is always reported only to the
controller process. If the controller is not the parent, then
the status is only reported via DG_XTRACE_WAIT_FOR_TARGET and
the traced state of the process will be invisible as far as
any wait3(2) calls made by the parent. If the controller is
the parent, the status is reported through either wait3(2) or
DG_XTRACE_WAIT_FOR_TARGET, but not both. The receipt of
signal status will be reported by whichever call is made
first; but if the other call is then made, the process will
already have been acknowledged and will not be reported again.
DG_XT_CONTINUE_TARGET
macro: DGXTRACECONTINUETARGET(process-id,
signal,
xtraceunionptr)
This request causes the target to resume execution. If the
signal argument is a valid signal number, the target resumes
execution as if it had incurred that signal. This request
will fail if signal is not 0 or a valid signal number, in
which case the error condition EIO is asserted. The request
will also fail with EIO if the caller is not the controller of
the target or the target is not stopped for tracing, though
the stop need not have been acknowledged with
DG_XTRACE_WAIT_FOR_TARGET. This request is focus-sensitive;
see the discussion of Target Focus below.
DG_XT_SINGLESTEP_TARGET
macro: DGXTRACESINGLESTEPTARGET(process-id,
signal,
xtraceunionptr)
This request will cause the target to continue execution for
one instruction. The target will be allowed to run with the
signal specified by signal and will take an exception after
executing its next instruction. This exception will cause it
to stop again for tracing. This request will fail if signal
is not a valid signal number. This request is focus-
sensitive; see the discussion of Target Focus below.
DG_XT_TERMINATE_TARGET
macro: DGXTRACETERMINATETARGET(process-id,
xtraceunionptr)
This request causes the target to terminate with the same
consequences as exit, except that the target will not stop for
tracing again as part of exit. The request will fail with EIO
if the caller is not the controller of the target or the
target is not stopped for tracing, though the stop need not
have been acknowledged with DG_XTRACE_WAIT_FOR_TARGET.
DG_XT_INHERIT_TRACE_ON_FORK
macro: DGXTRACEINHERITTRACEONFORK(process-id,
xtraceunionptr)
This request sets the inherittraceonfork flag for the
target. Having this flag set will cause any processes forked
by the target to be traced with the same controller.
DG_XT_STOP_ON_STORE
macro: DGXTRACESTOPONSTORE(process-id,
address,
length,
stoponstoreid,
xtraceunionptr)
This request causes the target to set a watch point at the
memory location specified by address for the length, in bytes,
specified by length. The address does not need to be a valid
part of the target's address space. Also, a length of zero
bytes is a legal parameter. This call returns to the
controller a unique stop-on-store ID. The maximum number of
watch points that may be set is governed by the value of
_PT_NUM_STOP_ON_STORE_IDS, which is defined in user.h. If
this limit is exceeded, dgxtrace will return EINVAL. When
the target writes to an area marked for stop-on-store, it will
report this event by sending a SIGTRAP signal without
arguments to itself. Then, when the process stops to handle
the signal, it will alert its controller that it has stopped
and can be debugged. The controller can then read the
target's address space to determine which stop-on-store
requests were hit. The requests will be identified by a bit
map returned in the DG value-added structure of the
ptrace_user structure. The bits corresponding to the stop-on-
store IDs that were hit will be set. See user.h for a
complete definition of the bit map. The stop-on-store
requests that the controller set are cleared when the
controller sends the message DG_XT_REMOVE_ALL_STOP_ON_STORE to
the target. This request will also remove the record of which
stop-on-store requests were hit. Because of this behavior,
the controller should read the target's user area before it
clears the requests.
DG_XT_REMOVE_ALL_STOP_ON_STORE
macro: DGXTRACEREMOVEALLSTOPONSTORE(process-id,
xtraceunionptr)
This request removes all stop-on-store requests. In doing so,
it also removes the record of which requests have been hit.
This request will always succeed, even if no stop-on-store
requests have been made.
DG_XT_GET_ADDRESS_SPACE_INFO
macro: DGXTGETADDRESSSPACEINFO(process-id,
keyptr,
addressspacemapptr,
xtraceunionptr)
This request allows the controller to obtain information about
the various address space segments (e.g., .text .data .bss) in
the process indicated by process-id. A value of
DG_XT_GET_ADDRESS_SPACE_INFO_INITIAL_KEY for the key will
obtain information about the first segment in the process.
dgxtrace will modify the value of the key to indicate the
next segment.
DG_XT_SET_MASKED_SIGNALS
macro: DGXTSETMASKEDSIGNALS(process-id,
signal-maskptr,
xtraceunionptr)
Normally, when a traced LWP takes delivery of a signal, the
signal is presented to the trace controller before the LWP
acts on it. The controller may use this request to mask off
signals it is not interested in examining. When a signal is
masked by the controller, the traced LWP will take delivery of
the signal as if it weren't being traced.
DG_XT_GET_MASKED_SIGNALS
macro: DGXTGETMASKEDSIGNALS(process-id,
signal-maskptr,
xtraceunionptr)
This request returns the set of signals that the controller
has indicated it is not interested in. See
DG_XT_SET_MASKED_SIGNALS above.
DG_XT_FOCUS
macro: DGXTFOCUS(process-id,
lwp-id,
xtraceunionptr)
The focused LWP affects the behavior of some dgxtrace
operations. Specifically, any dgxtrace operation that
reads/writes LWP-specific data will use the focus value to
determine which LWP will be read/written. Additionally, when
thread-focus continuation is enabled,process continuation
requests are focus-sensitive. Refer to the Target Focus
section below.
DG_XT_DUMP_CORE
macro: DGXTDUMPCORE(process-id,
path,
path-length,
xtraceunionptr)
This request instructs the target process to dump core into
the file indicated by path. path-length specifies the length
of the path, which must not exceed MAXPATHLEN characters (not
including the trailing null).
DG_XT_PROCESS_CONTROL
macro: DGXTPROCESSCONTROL(process-id,
version,
bitsptr,
xtraceunionptr)
This request allows the controller to adjust the trace control
bits of the target process identified by process-id. version
indicates the version of the process control request.
Currently, the only control bit available is
DG_XT_PCNTL_THREAD_FOCUS_CONTINUATION. Setting this bit makes
the process continuation requests sensitive to the thread
focus. See the Target Focus discussion below.
Target Focus
Several dgxtrace requests are sensitive to the trace controller's
LWP focus. Typically, requests that act only on LWPs use the
currently focused LWP as the target of the request. When a target
process stops for tracing, the pstatus space (see DG_XT_PSTATUS_SPACE
below) contains the initial focus in its focusedlwp field.
When the target's trace control DG_XT_PCNTL_THREAD_FOCUS_CONTINUATION
bit is set (see DG_XT_PROCESS_CONTROL, above), then requests that
resume process execution are also affected by the current LWP focus.
Specifically, if the focus is set to NOLWPID, then the resume request
is applied to all threads in the target process. If the current
focus is set to a specific LWP in the target process, then only that
LWP is resumed.
Target Spaces
The DG_XTRACE_READ_TARGET and DG_XTRACE_WRITE_TARGET macros use a
targetspace argument to indicate a subspace of the target's address
space. These spaces are described below.
DG_XT_USER_SPACE
Provides access to the ptrace_user structure described in
<sys/user.h> Use of this space is deprecated. Instead of
reading one data structure out of the kernel, you can read
several -- these are defined in <sys/dg_xtrace.h> and
described below.
DG_XT_ADDRESS_SPACE
This space is the address space directly accessible to the
target process.
DG_XT_PSTATUS_SPACE
This request is focus-insensitive. It provides access to the
dg_pstatus_t defined and described in <sys/dg_xtrace.h>. When
requesting this structure, the targetaddress specified must
be zero, and the number of bytes requested should match the
sizeof the dg_pstatus_t data structure. This structure is read
only; attempts to write this structure will result in an error
being returned by dgxtrace.
The numlwps field of this structure indicates how many LWP
IDs can be requested when using the DG_XT_ALL_LWPID_SPACE.
The numinterestinglwps field indicates how many LWP IDs can
be requested when using the DG_XT_INTERESTING_LWPID_SPACE
request.
DG_XT_LWPSTATUS_SPACE
This request is focus-sensitive. It allows the debugger to
read detailed LWP information in the form of the
dg_lwpstatus_t type, which is described in <sys/dg_xtrace.h>.
The <sys/dg_lwp.h> header file also includes a plethora of
detailed information for the <lwp_info> field within the
dg_lwpstatus_t type. When accessing this structure, the
targetaddress specified must be zero, and the number of bytes
requested should match the sizeof the dg_lwpstatus_t data
structure. When writing to this space, only the
machinecontext fields may be modified.
DG_XT_ALL_LWPID_SPACE
This space is focus-insensitive. It allows the trace
controller to read a list of LWPs that exist in the target
process. When using this request, the targetaddress
specified must be zero, and the number of bytes requested must
be congruent modulo the sizeof an LWP ID; that is, any size
that might allow for a partial LWP ID to be returned will be
flagged as an error. This space is read only; attempts to
write to it will cause an error to be returned by dgxtrace.
DG_XT_INTERESTING_LWPID_SPACE
This space is focus-insensitive. It allows the trace
controller to read a list of interesting LWPs that exist in
the target process. Interesting LWPs are ones that have
stopped for a particular reason, such as a breakpoint,
watchpoint, single-step (e.g., they were not stopped by the
operating system due to the actions of another thread).
(These threads will have a non-zero stopreason field in their
dg_lwpstatus_t structure. See DG_XT_LWPSTATUS_SPACE above).
When using this request, the targetaddress specified must be
zero, and the number of bytes requested must be congruent
modulo the sizeof an LWP ID (i.e., any size that might allow
for a partial LWP ID to be returned will be flagged as an
error). This space is read only; attempts to write to it will
cause an error it be returned by dgxtrace.
DG_XT_JOINING_LWPID_SPACE
This space is focus-sensitive. If the focused LWP is being
joined by any other LWPs (signified by the
DG_LWP_INFO_STATE1_BEING_JOINED bit being set in the
<lwpinfo>.<lwp_state1> field), the debugger can use the
<lwpinfo>.<num_joining_this_lwp> field to determine the
maximum number of LWPs that can be read with this request.
When using this request, the targetaddress specified must be
zero, and the number of bytes requested must be congruent
modulo the sizeof an LWP ID (i.e., any size that might allow
for a partial LWP ID to be returned will be flagged as an
error). This request is read only; attempts to write this
structure will cause an error to be returned by dgxtrace.
DG_XT_SYNC_QUEUE_SPACE
This space focus-insensitive. It used the sync queue ID from
the mutex or condition-variable as the target-address from
which to read the sync queue structure. The target-address
must be a valid sync queue ID, and the number of bytes
requested must be congruent modulo the sizeof
dg_xtrace_sync_queue_info_t (i.e., any size that might allow
for a partial sync queue to be written will be flagged as an
error). This request is read only; attempts to write this
structure will cause an error to be returned by dgxtrace.
DG_XT_RESOURCE_WAITERS_SPACE
This space focus-insensitive. Within a
dg_xtrace_sync_queue_info_t (obtained via the
DG_XT_SYNC_QUEUE_SPACE request), the numwaiters field
contains the number of LWPs awaiting this resource. This
value is the maximum number of dg_xtrace_resource_waiter_t
objects that can be read with this request. Each waiter
object contains a PID as well as an LWP ID, as these resources
can be shared across process boundaries. Note also that the
list actually read can be shorter than the numwaiters field
indicates because of changes that can occur in the other
referenced processes. Therefore, a termination marker must be
scanned for -- the termination marker is a PID value of NOPID
and an LWP ID value of NOLWPID.
The target-address must be a valid sync-queue ID from the
mutex and/or condition-variable of interest (see
<sys/dg_c_generics.h>). The number of bytes requested must be
congruent modulo the sizeof dg_xtrace_resource_waiter_t (i.e.,
any size that might allow for a partial resource waiter
structure to be written will be flagged as an error). This
request is read only; attempts to write this request will
cause an error to be returned by dgxtrace.
Set-user-id programs
To forestall possible fraud, dgxtrace inhibits the set-user-id
facility on subsequent exec calls. If a traced process calls exec,
it will stop before executing the first instruction of the new image
showing signal SIGTRAP.
ACCESS CONTROL
None.
RETURN VALUE
0 Completed successfully.
-1 An error occurred. errno is set to indicate the error.
DIAGNOSTICS
Errno may be set to one of the following error codes:
EIO Request is an illegal number.
ESRCH Process-id identifies a target that does not exist.
ESRCH No tracing relationship can be established.
EINVAL One of the arguments is invalid
EFAULT One of the arguments specifies a bad address.
SEE ALSO
exec(2), ptrace(2), signal(2), wait(2).
Licensed material--property of copyright holder(s)