unixdev.net


Switch to SpeakEasy.net DSL

The Modular Manual Browser

Home Page
Manual: (HP-UX-11.11)
Page:
Section:
Apropos / Subsearch:
optional field



 ptrace(2)							   ptrace(2)




 NAME
      ptrace() - process trace

 SYNOPSIS
      #include <&lt&lt&lt;sys/ptrace.h>&gt&gt&gt;

      int ptrace(
	   int request,
	   pid_t pid,
	   int addr,
	   int data,
	   int addr2
      );

    Remarks
      Much of the functionality of ptrace() is highly dependent on the
      underlying hardware.  An application that uses this system call should
      not be expected to be portable across architectures or implementations.

 DESCRIPTION
      The ptrace() system call provides a means by which a process can
      control the execution of another process.	 Its primary use is for the
      implementation of breakpoint debugging (see adb(1)).  The traced
      process behaves normally until it encounters a signal (see signal(2)
      for the list), at which time it enters a stopped state and the tracing
      process is notified via wait() (see wait(2)).

      A traced process may also enter the stopped state without encountering
      a signal.	 This can happen if the traced process stops in response to
      specific events that it encounters during the course of its execution.
      To make this happen, the tracing process has to set specific event
      flags in the context of the traced process.  This mechanism will be
      described later in greater detail.

      When the traced process is in the stopped state, the tracing process
      can use ptrace() to examine and modify the "core image".	Also, the
      tracing process can cause the traced process to either terminate or
      continue, with the possibility of ignoring the signal that caused it
      to stop.

      To forestall possible fraud, ptrace() inhibits the set-user-ID
      facility on subsequent exec*() calls.  If a traced process calls
      exec*(), it stops before executing the first instruction of the new
      image, showing signal SIGTRAP.

      The request argument determines the precise action to be taken by
      ptrace().	 It is one of the values described in the rest of this
      section.

      The following request is used by the child process that will be
      traced.



 Hewlett-Packard Company	    - 1 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




	   PT_SETTRC	  This request must be issued by a child process if
			  it is to be traced by its parent.  It turns on the
			  child's trace flag, which stipulates that the
			  child should be left in a stopped state upon
			  receipt of a signal rather than the state
			  specified by func (see signal(2)).  The pid, addr,
			  data, and addr2 arguments are ignored, and a
			  return value is not defined for this request.
			  Peculiar results occur if the parent does not
			  expect to trace the child.

      The remainder of the requests can only be used by the tracing process.
      For each, pid is the process ID of the process being traced, which
      must be in a stopped state before these requests are made.  The
      responsibility of ensuring that the traced process is in a stopped
      state before a request is issued, lies with the tracing process.

	   PT_RDUSER
	   PT_RIUSER	  With these requests, the word at location addr in
			  the address space of the traced process is
			  returned to the tracing process.  If instruction
			  (I) and data (D) space are separated, request
			  PT_RIUSER returns a word from I space, and request
			  PT_RDUSER returns a word from D space.  If I and D
			  space are not separated, either request produces
			  equivalent results.  The data and addr2 arguments
			  are ignored.

			  These two requests fail if addr is not the start
			  address of a word, in which case a value of -1 is
			  returned to the tracing process and its errno is
			  set to [EIO].

	   PT_RUAREA	  With this request, the word at location addr in
			  the user area of the traced process in the
			  system's address space (see <&lt&lt&lt;sys/user.h>&gt&gt&gt;) is
			  returned to the tracing process.  Addresses in
			  this area are system dependent, but start at zero.
			  The limit can be derived from <&lt&lt&lt;sys/user.h>&gt&gt&gt;.  The
			  data and addr2 arguments are ignored.

			  This request fails if addr is not the start
			  address of a word or is outside the user area, in
			  which case a value of -1 is returned to the
			  tracing process and its errno is set to [EIO].

	   PT_WDUSER
	   PT_WIUSER	  With these requests, the value given by the data
			  argument is written into the address space of the
			  traced process at location addr.  PT_WIUSER writes
			  a word into I space, and PT_WDUSER writes a word



 Hewlett-Packard Company	    - 2 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




			  in D space.  Upon successful completion, the value
			  written into the address space of the traced
			  process is returned to the tracing process.  The
			  addr2 argument is ignored.

			  These two requests fail if addr is not the start
			  address of a word, or if addr is a location in a
			  pure procedure space and either another process is
			  executing in that space or the tracing process
			  does not have write access for the executable file
			  corresponding to that space.	Upon failure, a
			  value of -1 is returned to the tracing process and
			  its errno is set to [EIO].

	   PT_WUAREA	  This request is not supported.  Therefore, it
			  returns -1, sets errno to [EIO] and does not
			  affect the user area of the traced process.

	   PT_RUREGS	  With this request, the word at location addr in
			  the save_state structure at the base of the per-
			  process kernel stack is returned to the tracing
			  process.  addr must be word-aligned and less than
			  STACKSIZE*NBPG (see <&lt&lt&lt;sys/param.h>&gt&gt&gt; and
			  <&lt&lt&lt;machine/param.h>&gt&gt&gt;).  The save_state structure
			  contains the registers and other information about
			  the process.	The data and addr2 arguments are
			  ignored.

	   PT_WUREGS	  The save_state structure at the base of the per-
			  process kernel stack is written as it is read with
			  request PT_RUREGS.  Only a few locations can be
			  written in this way: the general registers, most
			  floating-point registers, a few control registers,
			  and certain bits of the interruption processor
			  status word.	The addr2 argument is ignored.

	   PT_RDDATA
	   PT_RDTEXT	  These requests are identical to PT_RDUSER and
			  PT_RIUSER, except that the data argument specifies
			  the number of bytes to read and the addr2 argument
			  specifies where to store that data in the tracing
			  process.

	   PT_WRDATA
	   PT_WRTEXT	  These requests are identical to PT_WDUSER and
			  PT_WIUSER, except that the data argument specifies
			  the number of bytes to write and the addr2
			  argument specifies where to read that data in the
			  tracing process.





 Hewlett-Packard Company	    - 3 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




	   PT_CONTIN	  This request causes the traced process to resume
			  execution.  If the data argument is 0, all pending
			  signals, including the one that caused the traced
			  process to stop, are canceled before it resumes
			  execution.  If the data argument is a valid signal
			  number, the traced process resumes execution as if
			  it had incurred that signal, and any other pending
			  signals are canceled.	 The addr2 argument is
			  ignored.

			  If the addr argument is not 1, the Instruction
			  Address Offset Queue (program counter) is loaded
			  with the values addr and addr+4 before execution
			  resumes.  Otherwise, execution resumes from the
			  point where it was interrupted.

			  Upon successful completion, the value of data is
			  returned to the tracing process.

			  This request fails if data is not 0 or a valid
			  signal number, in which case a value of -1 is
			  returned to the tracing process and its errno is
			  set to [EIO].

	   PT_EXIT	  This request causes the traced process to
			  terminate with the same consequences as exit().
			  The addr, data, and addr2 arguments are ignored.

	   PT_SINGLE	  This request causes a flag to be set so that an
			  interrupt occurs upon the completion of one
			  machine instruction.	It then executes the same
			  steps as listed above for request PT_CONTIN.	If
			  the processor does not provide a trace bit, this
			  request returns an error.  This effectively allows
			  single-stepping of the traced process.

			  Whether or not the trace bit remains set after
			  this interrupt is a function of the hardware.

	   PT_ATTACH	  This request stops the process identified by pid
			  and allows the calling process to trace it.
			  Process pid does not have to be a child of the
			  calling process, but the effective user ID of the
			  calling process must match the real and saved user
			  ID of process pid unless the effective user ID of
			  the tracing process is superuser.  The calling
			  process can use the wait() system call to wait for
			  process pid to stop.	The addr, data, and addr2
			  arguments are ignored.





 Hewlett-Packard Company	    - 4 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




	   PT_DETACH	  This request detaches the traced process pid and
			  allows it to continue its execution in the manner
			  of PT_CONTIN.

			  If the addr argument is not 1, the Instruction
			  Address Offset Queue (program counter) is loaded
			  with the values addr and addr2.

	   PT_CONTIN1	  This request causes the traced process to resume
			  execution with all its pending signals intact.  If
			  the data argument is 0, the signal that caused the
			  traced process to stop is canceled before the
			  traced process resumes execution.  If the data
			  argument is a valid signal number, the traced
			  process resumes execution as if it had received
			  that signal.	The addr argument must be equal to 1
			  for this request.  The addr2 argument is ignored.
			  Upon successful completion, the value of data is
			  returned to the tracing process.

			  This request fails if data is not 0 or a valid
			  signal number, in which case a value of -1 is
			  returned to the tracing process and its errno is
			  set to [EIO].

	   PT_SINGLE1	  This request causes a flag to be set so that an
			  interrupt occurs upon the completion of one
			  machine instruction.	It then executes the same
			  steps as listed above for request PT_CONTIN1.	 If
			  the processor does not provide a trace bit, this
			  request returns an error.  This effectively allows
			  single stepping of the traced process.

			  Whether or not the trace bit remains set after
			  this interrupt is a function of the hardware.

      As noted earlier, a tracing process can set event flags in the context
      of the traced process to make it respond to specific events, during
      its execution.  These events are:

	   PTRACE_SIGNAL  This event flag indicates that, when processing
			  signals, the traced process needs to examine
			  signal mask bits set in its context by the tracing
			  process.  See the ptrace_event structure
			  description under PT_SET_EVENT_MASK for further
			  details.

			  If the signal being processed has its signal mask
			  bit set, signal processing continues as though the
			  process were not traced.  The traced process is
			  not stopped and the tracing process is not



 Hewlett-Packard Company	    - 5 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




			  notified of the signal.  If the signal mask bit is
			  not set for the signal being processed, the traced
			  process is stopped and the tracing process is
			  notified via wait() (see wait(2)).

			  Note that the SIGKILL signal is an exception to
			  this rule in that it can never be unmasked; that
			  is, it behaves as though its mask bit were always
			  set, regardless of whether or not its mask bit is
			  in fact set.	Consequently, a SIGKILL signal
			  cannot be used to stop a traced process.

			  In this respect, a SIGTRAP signal is also special
			  in that it is specifically used to stop traced
			  processes.  A SIGTRAP signal should therefore
			  never be masked.  Setting a mask bit for SIGTRAP
			  will result in unexpected system behavior.

	   PTRACE_FORK	  This event flag indicates that the traced process
			  needs to take special action when it invokes
			  fork().  When set, both the parent and child
			  processes stop (the child after marking itself as
			  a traced process and adopting its parent's
			  debugger).  Both processes log the fact that they
			  stopped in response to a PTRACE_FORK event.
			  Further, the child's pid is logged in the parent's
			  context, and the parent's pid is logged in the
			  child's context.  The child does not inherit its
			  parent's event flags.	 See the ptrace_state
			  structure description under PT_GET_PROCESS_STATE
			  for further details.

	   PTRACE_VFORK	  This event flag indicates that the traced process
			  needs to take special action when it invokes
			  vfork().  When set, the child process stops after
			  marking itself as a traced process and adopting
			  its parent's debugger.  The fact that a
			  PTRACE_VFORK event was responded to is logged in
			  the context of both the parent and child
			  processes.  Further, the child's pid is logged in
			  the parent's context, and the parent's pid is
			  logged in the child's context.  The child does not
			  inherit its parent's event flags.  See the
			  ptrace_state structure description under
			  PT_GET_PROCESS_STATE for further details.  It is
			  important to note that the warnings with respect
			  to vfork() (see vfork(2)), continue to apply here.
			  In particular, it needs to be remembered that,
			  when the child process stops, its parent process
			  is suspended, and that the child borrows the
			  parent's memory and thread of control until a call



 Hewlett-Packard Company	    - 6 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




			  to exec*() or an exit (either by a call to exit()
			  or abnormally (see exec(2) and exit(2))).

	   PTRACE_EXEC	  This event flag indicates that the traced process
			  needs to take special action when it invokes
			  exec*().  When set, the traced process stops after
			  logging the fact that it stopped in response to a
			  PTRACE_EXEC event.  It also logs information
			  pertaining to the path or file argument of
			  exec*().  This includes a pointer to the path name
			  string and the length of the path name string.
			  See the ptrace_state structure description under
			  PT_GET_PROCESS_STATE for further details.

	   PTRACE_EXIT	  This event flag indicates that the traced process
			  needs to take special action when it invokes
			  exit().  When set, the traced process stops after
			  logging the fact that it stopped in response to a
			  PTRACE_EXIT event.

	   PT_SET_EVENT_MASK
			  This request is used by the calling process to
			  specify event flags and signal mask values that it
			  wants the traced process to respond to.  It does
			  so by writing the contents of the ptrace_event
			  data structure in the user space pointed to by
			  addr into the context of the traced process.	The
			  data argument specifies the number of bytes to be
			  transferred.	The addr2 argument is ignored.

			  The request fails if the number of bytes specified
			  is less than zero or greater than the size of the
			  ptrace_event structure, and its errno is set to
			  [EIO].

			       typedef struct ptrace_event{
				    sigset_t  pe_signals;
				    events_t  pe_set_event;
			       } ptrace_event_t;

			  Event flags are set in the pe_set_event member of
			  the ptrace_event data structure.  An event flag is
			  set when the tracing process wants the traced
			  process to respond to a particular event.  As
			  detailed earlier, the event flags defined are
			  PTRACE_EXEC, PTRACE_EXIT, PTRACE_FORK,
			  PTRACE_SIGNAL, and PTRACE_VFORK.  See the
			  definition of events_t in <&lt&lt&lt;sys/ptrace.h>&gt&gt&gt; for more
			  details.





 Hewlett-Packard Company	    - 7 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




			  Signal mask values are set in the pe_signals
			  member of the ptrace_event structure.	 This field
			  is qualified by a PTRACE_SIGNAL event flag being
			  set in the pe_set_event member.  Mask values set
			  in the pe_signals member correspond to signals
			  that need to be masked from the tracing process
			  when received by the traced process; that is,
			  these are signals received by the traced process
			  that the tracing process does not want to be
			  informed about.  The pe_signals member is
			  described by the type definition sigset_t, which
			  is defined in <&lt&lt&lt;signal.h>&gt&gt&gt;.

	   PT_GET_EVENT_MASK
			  This request is used by the calling process to
			  determine the event flags and signal mask values
			  that have been set in the traced process's context
			  by the last PT_SET_EVENT_MASK request.  The data
			  argument specifies the number bytes to be read
			  from the context of the traced process into the
			  ptrace_event data structure in user space pointed
			  to by addr . The addr2 argument is ignored.

			  The request fails if the number of bytes requested
			  is less than zero or greater than the size of the
			  ptrace_event structure, and its errno is set to
			  [EIO].

	   PT_GET_PROCESS_STATE
			  This request is used by the calling process to
			  access state information logged by the traced
			  process after it (the traced process) has
			  responded to an event.  The request reads data
			  bytes of data from the traced process's context
			  into the ptrace_state data structure in user space
			  pointed to by addr . The addr2 argument is
			  ignored.

			  The ptrace_state data structure is described in
			  <&lt&lt&lt;sys/ptrace.h>&gt&gt&gt; and has the following members:

			       typedef struct ptrace_state{
				    events_t  pe_report_event;
				    int	      pe_path_len;
				    pid_t     pe_other_pid;
			       } ptrace_state_t;

			  The event that the traced process responded to and
			  stopped is logged in the pe_report_event member.
			  One of PTRACE_EXEC, PTRACE_EXIT, PTRACE_FORK,
			  PTRACE_SIGNAL, or PTRACE_VFORK is logged here.



 Hewlett-Packard Company	    - 8 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




			  See the definition of events_t in <&lt&lt&lt;sys/ptrace.h>&gt&gt&gt;
			  for more details.

			  If the event that the traced process responded to
			  was PTRACE_EXEC, then the pe_path_len member
			  provides the length of the path name string (which
			  is the path name of the executable file) not
			  including the null terminating character.

			  If the event that the traced process responded to
			  was PTRACE_FORK or PTRACE_VFORK, then the
			  pe_other_pid member provides the parent's pid when
			  accessed from the child's context, and the child's
			  pid when accessed from the parent's context.

			  The request fails if the number of bytes requested
			  is less than zero or greater than the size of the
			  ptrace_event structure and its errno is set to
			  [EIO].

	   PT_GET_PROCESS_PATHNAME
			  If the event that the traced process responded to
			  and stopped was PTRACE_EXEC, then this request is
			  used by the calling process to access the path
			  name of the executable file provided as a path or
			  file argument to exec*().  The request reads data
			  bytes of data of the path name string from the
			  traced process's context into the data buffer in
			  user space pointed to by addr . The addr2 argument
			  is ignored.  In the typical case, data is equal to
			  the value of the pe_path_len member of the
			  ptrace_state structure returned via the
			  PT_GET_PROCESS_STATE request.

			  If the number of bytes requested is greater than
			  zero but less than the length of the path name
			  string, then the number of bytes requested is
			  returned.  If the number of bytes requested is
			  greater than the length of the path name string,
			  then the full path name string (including the null
			  terminating character) is returned.

			  The request fails if the number of bytes requested
			  is less than zero, and its errno is set to [EIO].

 EXAMPLES
      The following example illustrates the use of some of the ptrace()
      requests by a tracing process.

      #include <&lt&lt&lt;stdio.h>&gt&gt&gt;
      #include <&lt&lt&lt;signal.h>&gt&gt&gt;



 Hewlett-Packard Company	    - 9 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




      #include <&lt&lt&lt;sys/wait.h>&gt&gt&gt;
      #include <&lt&lt&lt;sys/ptrace.h>&gt&gt&gt;
      #define BUFSIZ  1024
      #define MAXPATH 1024

      pid_t	      npid, cpid, pid;
      int	      status, errors=0, pathlength;
      ptrace_event_t  *event_addr;
      ptrace_state_t  *state_addr;
      char	      *buf_addr;
      size_t	      event_len, state_len;
      int	      filed[2];

      child()
      {
	  int n, bar;

	  close(filed[1]);
	  /* Wait for parent to write to pipe */
	  while ((n = read(filed[0], &&amp&amp&amp;bar, BUFSIZ)) == 0);

	  /* Now the child can exec. */
	  if (execlp("ls", "ls", (char *)0) <&lt&lt&lt; 0)   /* error during exec */
		  printf("Child: exec failed\n");
	  exit(0);
      }

      parent()
      {
	  close(filed[0]);

	  /* Before child does an exec, attach it and set its event flag. */
	  if (ptrace(PT_ATTACH,pid))  /* failed to attach process */
	      printf("Parent: Failed to attach child\n");
	  if (pid != wait(&&amp&amp&amp;status))   /* wait failed */
	      printf("Parent: attach failed with wrong wait status\n");
	  if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
	      printf("Parent: SIGTRAP didn't stop child\n");

	  /*
	   * The child process has now stopped.	 Set its event flag indicating
	   * that it needs to trigger on a PTRACE_EXEC event.
	   */
	  event_addr->&gt&gt&gt;pe_set_event = PTRACE_EXEC;
	  if (ptrace(PT_SET_EVENT_MASK, pid, event_addr, event_len))
	      printf("Parent: PT_SET_EVENT_MASK ptrace request failed\n");
	  if (pid != wait(&&amp&amp&amp;status))   /* wait failed */
	      printf("Parent: wait() failed with wrong wait status\n");

	  /*
	   * Send the child a message so it can break out of the while loop.



 Hewlett-Packard Company	   - 10 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




	   * Get it running so it can exec.
	   */
	  write(filed[1], "now run", 7);
	  if (ptrace(PT_CONTIN, pid, 1, 0) != 0)
	      printf("Parent: failed to get child process running\n");
	  /*
	   * Wait for the traced child to stop after the exec system call in
	   * response to an exec event set in its ptrace_event structure.
	   */
	  if (pid != (npid = wait(&&amp&amp&amp;status)))   /* wait failed */
	      printf("Parent: wait() failed with wrong status\n");
	  if (!WIFSTOPPED(status))
	      printf("Parent: invalid wait() completion\n");

	  /*
	   * Child has stopped; fetch its process state and examine state
	   * information.
	   */
	  if (ptrace(PT_GET_PROCESS_STATE, pid, state_addr, state_len) <&lt&lt&lt; 0)
	      printf("Parent: PT_GET_PROCESS_STATE ptrace request failed\n");
	  if (pid != wait(&&amp&amp&amp;status))   /* wait failed */
	      printf("Parent: wait() failed with wrong wait status\n");

	  /* Check if the pathlength value returned is non-zero */
	  if ((pathlength = state_addr->&gt&gt&gt;pe_path_len) == 0)
	      printf("Parent: zero length pathname returned\n");

	  /* Fetch exec'd file pathname and store it in the buffer. */
	  if (ptrace(PT_GET_PROCESS_PATHNAME, pid, buf_addr, (pathlength+1))
	      <&lt&lt&lt; 0){
	      printf("Parent: Failed to get exec pathname\n");
	  } else {
	      printf("Parent: the exec pathname is %s\n", buf_addr);
	      if (pid != wait(&&amp&amp&amp;status))	  /* wait failed */
		  printf("Parent: wait() failed with wrong status\n");
	  }
      }

      main()
      {
	  event_len = sizeof(ptrace_event_t);
	  state_len = sizeof(ptrace_state_t);
	  event_addr = calloc(event_len, 1);
	  state_addr = calloc(state_len, 1);
	  buf_addr = calloc(MAXPATH, 1);
	  pipe(filed);
	  switch (pid = fork()) {
	      case -1:
		  exit(1);
	      case 0:
		  child();



 Hewlett-Packard Company	   - 11 -   HP-UX Release 11i: November 2000






 ptrace(2)							   ptrace(2)




		  break;
	      default:
		  parent();
		  break;
	  }
      }

 ERRORS
      If ptrace() fails, errno is set to one of the following values.

	   [EACCES]	  The executable image of the process being attached
			  resides across an interruptible NFS mount.

	   [EIO]	  request is an illegal number.

	   [EIO]	  The PT_SETTRC request is used with a data argument
			  that is less than zero or not a multiple of four,
			  or data is not word-aligned.

	   [EIO]	  Attempting to write to a memory segment of the
			  traced process that is not writable, or attempting
			  to write to page 0, or the request argument is out
			  of range.

	   [EIO]	  The PT_CONTIN request is being used with an
			  invalid data argument (signal number).

	   [EIO]	  Attempting to write to the user area via the
			  PT_WUAREA request.

	   [EPERM]	  The specified process cannot be attached for
			  tracing.

	   [EPERM]	  The process pid is already being traced or pid
			  refers to the calling process itself.

	   [ESRCH]	  pid identifies a process to be traced that does
			  not exist or has not executed a ptrace() with
			  request PT_SETTRC.

 SEE ALSO
      adb(1), exec(2), exit(2), signal(2), ttrace(2), wait(2).

 STANDARDS CONFORMANCE
      ptrace(): SVID2, SVID3, XPG2









 Hewlett-Packard Company	   - 12 -   HP-UX Release 11i: November 2000