11.5 proc Provider

11.5.1 Probes
11.5.2 Arguments
11.5.3 lwpsinfo_t
11.5.4 psinfo_t
11.5.5 Examples
11.5.6 Stability

The proc provider makes available probes pertaining to the following activities: process creation and termination, LWP creation and termination, executing new program images, and sending and handling signals.

11.5.1 Probes

Table 11.3, “proc Probes” lists the proc probes.

Table 11.3 proc Probes

Probe

Description

create

Fires when a process (or process thread) is created using fork() or vfork() (which both invoke clone()). The psinfo_t corresponding to the new child process is pointed to by args[0].

exec

Fires whenever a process loads a new process image using a variant of the execve() system call. The exec probe fires before the process image is loaded. Process variables like execname and curpsinfo therefore contain the process state before the image is loaded. Some time after the exec probe fires, either the exec-failure or exec-success probe subsequently fires in the same thread. The path of the new process image is pointed to by args[0].

exec-failure

Fires when an exec() variant has failed. The exec-failure probe fires only after the exec probe has fired in the same thread. The errno value is provided in args[0].

exec-success

Fires when an exec() variant has succeeded. Like the exec-failure probe, the exec-success probe fires only after the exec probe has fired in the same thread. By the time that the exec-success probe fires, process variables like execname and curpsinfo contain the process state after the new process image has been loaded.

exit

Fires when the current process is exiting. The reason for exit, which is expressed as one of the SIGCHLD <asm-generic/signal.h> codes, is contained in args[0].

lwp-create

Fires when a process thread is created, the latter typically as a result of pthread_create(). The lwpsinfo_t corresponding to the new thread is pointed to by args[0]. The psinfo_t of the process that created the thread is pointed to by args[1].

lwp-exit

Fires when a process or process thread is exiting, due either to a signal or to an explicit call to exit or pthread_exit().

lwp-start

Fires within the context of a newly created process or process thread. The lwp-start probe fires before any user-level instructions are executed. If the thread is the first created for the process, the start probe fires, followed by lwp-start.

signal-clear

Probes that fires when a pending signal is cleared because the target thread was waiting for the signal in sigwait(), sigwaitinfo(), or sigtimedwait(). Under these conditions, the pending signal is cleared and the signal number is returned to the caller. The signal number is in args[0]. signal-clear fires in the context of the formerly waiting thread.

signal-discard

Fires when a signal is sent to a single-threaded process, and the signal is both unblocked and ignored by the process. Under these conditions, the signal is discarded on generation. The lwpsinfo_t and psinfo_t of the target process and thread are in args[0] and args[1], respectively. The signal number is in args[2].

signal-handle

Fires immediately before a thread handles a signal. The signal-handle probe fires in the context of the thread that will handle the signal. The signal number is in args[0]. A pointer to the siginfo_t structure that corresponds to the signal is in args[1]. The address of the signal handler in the process is in args[2].

signal-send

Fires when a signal is sent to a process or to a thread created by a process. The signal-send probe fires in the context of the sending process or thread. The lwpsinfo_t and psinfo_t of the receiving process and thread are in args[0] and args[1], respectively. The signal number is in args[2]. signal-send is always followed by signal-handle or signal-clear in the receiving process and thread.

start

Fires in the context of a newly created process. The start probe fires before any user-level instructions are executed in the process.


Note

In Oracle Linux, there is no fundamental difference between a process and a thread that a process creates. The threads of a process are set up so that they can share resources, but each thread has its own entry in the process table with its own process ID.

11.5.2 Arguments

Table 11.4, “proc Probe Arguments” lists the argument types for the proc probes. See Table 11.3, “proc Probes” for a description of the arguments.

Table 11.4 proc Probe Arguments

Probe

args[0]

args[1]

args[2]

create

psinfo_t *

exec

char *

exec-failure

int

exec-success

exit

int

lwp-create

lwpsinfo_t *

psinfo_t *

lwp-exit

lwp-start

signal-clear

int

signal-discard

lwpsinfo_t *

psinfo_t *

int

signal-handle

int

siginfo_t *

void (*)(void)

signal-send

lwpsinfo_t *

psinfo_t *

int

start


11.5.3 lwpsinfo_t

Several proc probes have arguments of type lwpsinfo_t. The definition of the lwpsinfo_t structure as available to DTrace consumers is as follows:

typedef struct lwpsinfo {
  int pr_flag;                /* flags */
  id_t pr_lwpid;              /* thread id */
  uintptr_t pr_addr;          /* internal address of thread */
  uintptr_t pr_wchan;         /* not supported */
  char pr_stype;              /* not supported */
  char pr_state;              /* numeric thread state */
  char pr_sname;              /* printable character for pr_state */
  int pr_pri;                 /* priority, high value = high priority */
  char pr_name[PRCLSZ];       /* scheduling class name */
  processorid_t pr_onpro;     /* processor which last ran this thread */
} lwpsinfo_t;
Note

Lightweight processes do not exist on Oracle Linux. In Oracle Linux, processes and threads are both represented by process descriptors of type struct task_struct in the task list. DTrace translates the members of lwpsinfo_t from the task_struct for the Oracle Linux process.

pr_flag is set to 1 if the thread is stopped. Otherwise, it is set to 0.

Table 11.5, “pr_state Values” lists the values that pr_state can take, together with the corresponding character values for pr_sname.

Table 11.5 pr_state Values

pr_state Value

pr_sname Value

Description

SRUN (2)

R

The thread is runnable or is currently running on a CPU. The sched:::enqueue probe fires immediately before a thread's state is transitioned to SRUN. The sched:::on-cpu probe will fire a short time after the thread starts to run.

The equivalent Oracle Linux task state is TASK_RUNNING.

SSLEEP (1)

S

The thread is sleeping. The sched:::sleep probe will fire immediately before a thread's state is transitioned to SSLEEP.

The equivalent Oracle Linux task state is TASK_INTERRUPTABLE or TASK_UNINTERRUPTABLE.

SSTOP (4)

T

The thread is stopped, either due to an explicit proc directive or some other stopping mechanism.

The equivalent Oracle Linux task state is __TASK_STOPPED or __TASK_TRACED.

SWAIT (7)

W

The thread is waiting on wait queue. The sched:::cpucaps-sleep probe will fire immediately before the thread's state transitions to SWAIT.

The equivalent Oracle Linux task state is TASK_WAKEKILL or TASK_WAKING.

SZOMB (3)

Z

The thread is a zombie.

The equivalent Oracle Linux task state is EXIT_ZOMBIE, EXIT_DEAD, or TASK_DEAD.


11.5.4 psinfo_t

Several proc probes have an argument of type psinfo_t. The definition of the psinfo_t structure as available to DTrace consumers is as follows:

typedef struct psinfo {
        int pr_flag;                    /* process flags (deprecated) */
        int pr_nlwp;                    /* not supported */
        pid_t pr_pid;                   /* unique process id */
        pid_t pr_ppid;                  /* process id of parent */
        pid_t pr_pgid;                  /* pid of process group leader */
        pid_t pr_sid;                   /* session id */
        uid_t pr_uid;                   /* real user id */
        uid_t pr_euid;                  /* effective user id */
        uid_t pr_gid;                   /* real group id */
        uid_t pr_egid;                  /* effective group id */
        uintptr_t pr_addr;              /* address of process */
        size_t pr_size;                 /* not supported */
        size_t pr_rssize;               /* not supported */
        struct tty_struct *pr_ttydev;   /* controlling tty (or -1) */
        ushort_t pr_pctcpu;             /* not supported */
        ushort_t pr_pctmem;             /* not supported */
        timestruc_t pr_start;           /* process start time */
        timestruc_t pr_time;            /* not supported */
        timestruc_t pr_ctime;           /* not supported */
        char pr_fname[16];              /* name of exec'ed file */
        char pr_psargs[80];             /* initial chars of arg list */
        int pr_wstat;                   /* not supported */
        int pr_argc;                    /* initial argument count */
        uintptr_t pr_argv;              /* address of initial arg vector */
        uintptr_t pr_envp;              /* address of initial env vector */
        char pr_dmodel;                 /* data model */
        taskid_t pr_taskid;             /* not supported */
        projid_t pr_projid;             /* not supported */
        int pr_nzomb;                   /* not supported */
        poolid_t pr_poolid;             /* not supported */
        zoneid_t pr_zoneid;             /* not supported */
        id_t pr_contract;               /* not supported */
        lwpsinfo_t pr_lwp;              /* not supported */
} psinfo_t;
Note

Lightweight processes do not exist on Oracle Linux. In Oracle Linux, processes and threads are both represented by process descriptors of type struct task_struct in the task list. DTrace translates the members of psinfo_t from the task_struct for the Oracle Linux process.

pr_dmodel is set to either PR_MODEL_ILP32, denoting a 32–bit process, or PR_MODEL_LP64, denoting a 64–bit process.

11.5.5 Examples

The following sections provide examples of using probes published by the proc provider.

11.5.5.1 exec

You can use the exec probe to easily determine which programs are being executed, and by whom, as shown in the following example:

#pragma D option quiet

proc:::exec
{
  self->parent = execname;
}

proc:::exec-success
/self->parent != NULL/
{
  @[self->parent, execname] = count();
  self->parent = NULL;
}

proc:::exec-failure
/self->parent != NULL/
{
  self->parent = NULL;
}

END
{
  printf("%-20s %-20s %s\n", "WHO", "WHAT", "COUNT");
  printa("%-20s %-20s %@d\n", @);
}

Running the example script for a short period of time results in output similar to the following example:

# dtrace -s ./whoexec.d 
^C
WHO                  WHAT                 COUNT
abrtd                abrt-handle-eve      1
firefox              basename             1
firefox              mkdir                1
firefox              mozilla-plugin-      1
firefox              mozilla-xremote      1
firefox              run-mozilla.sh       1
firefox              uname                1
gnome-panel          firefox              1
kworker/u:1          modprobe             1
modprobe             modprobe.ksplic      1
mozilla-plugin-      plugin-config        1
mozilla-plugin-      uname                1
nice                 sosreport            1
run-mozilla.sh       basename             1
run-mozilla.sh       dirname              1
run-mozilla.sh       firefox              1
run-mozilla.sh       uname                1
sh                   abrt-action-sav      1
sh                   blkid                1
sh                   brctl                1
sh                   cut                  1
...

11.5.5.2 start and exit

If you want to know how long programs are running from creation to termination, you can enable the start and exit probes, as shown in the following example:

proc:::start
{
  self->start = timestamp;
}

proc:::exit
/self->start/
{
  @[execname] = quantize(timestamp - self->start);
  self->start = 0;
}

Running the example script for several seconds on a build server results in output similar to the following example:

# dtrace -s ./progtime.d
dtrace: script ’./progtime.d’ matched 2 probes
^C
...
cc
          value  ------------- Distribution ------------- count
       33554432 |                                         0
       67108864 |@@@                                      3
      134217728 |@                                        1
      268435456 |                                         0
      536870912 |@@@@                                     4
     1073741824 |@@@@@@@@@@@@@@                           13
     2147483648 |@@@@@@@@@@@@                             11
     4294967296 |@@@                                      3
     8589934592 |                                         0

sh
          value  ------------- Distribution ------------- count
         262144 |                                         0
         524288 |@                                        5
        1048576 |@@@@@@@                                  29
        2097152 |                                         0
        4194304 |                                         0
        8388608 |@@@                                      12
       16777216 |@@                                       9
       33554432 |@@                                       9
       67108864 |@@                                       8
      134217728 |@                                        7
      268435456 |@@@@@                                    20
      536870912 |@@@@@@                                   26
     1073741824 |@@@                                      14
     2147483648 |@@                                       11
     4294967296 |                                         3
     8589934592 |                                         1
    17179869184 |                                         0
...

11.5.5.3 signal-send

You can use the signal-send probe to determine the sending and receiving process associated with any signal, as shown in the following example:

#pragma D option quiet

proc:::signal-send
{
  @[execname, stringof(args[1]->pr_fname), args[2]] = count();
}

END
{
  printf("%20s %20s %12s %s\n",
      "SENDER", "RECIPIENT", "SIG", "COUNT");
  printa("%20s %20s %12d %@d\n", @);
}

Running this script results in output similar to the following example:

# dtrace -s sig.d
^C
              SENDER            RECIPIENT          SIG COUNT
         gnome-panel                 Xorg           29 1
         kworker/0:2               dtrace            2 1
                Xorg                 Xorg           29 3
                java                 Xorg           29 6
             firefox                 Xorg           29 14
         kworker/0:0                 Xorg           29 1135

11.5.6 Stability

The proc provider uses DTrace's stability mechanism to describe its stabilities, as shown in the following table.

Element

Name Stability

Data Stability

Dependency Class

Provider

Evolving

Evolving

ISA

Module

Private

Private

Unknown

Function

Private

Private

Unknown

Name

Evolving

Evolving

ISA

Arguments

Evolving

Evolving

ISA

For more information about the stability mechanism, see Chapter 15, Stability.