dg_xtrace(2) SDK R4.11 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
Xtrace 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 can not 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 (who 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 if of the form
DGXTRACEname([arguments])
where name is the same as the corresponding name in request.
arguments includes 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 The subspace of the process's address space (Visible
Address Space or User Area) to which a read/write
operation is directed: DG_XT_USER_SPACE or
DG_XT_ADDRESS_SPACE
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.
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.
DG_XT_WAIT_FOR_TARGET
macro: DGXTRACEWAITFORTARGET(process-id-ptr,
waitptr,
options,
xtraceunionptr)
With this request, the controlling process waits for one of
his traced 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 have 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.
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_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.
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 will also remove the record of which stop on
store requests were hit. Because of this, 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.
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)