Proc Provider

The proc provider makes available the probes that pertain to the following activities: process creation and termination, LWP creation and termination, execution of new program images, and signal sending and handling.

proc Probes

The probes for the proc provider are listed in the following table.

Table 8-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:

No fundamental difference between a process and a thread that a process creates, exists in Linux. 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.

proc Probe Arguments

The following table lists the argument types for the proc probes. See proc Probes for a description of the arguments.

Table 8-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

lwpsinfo_t

Several proc probes have arguments of type lwpsinfo_t. Detailed information about this data structure can be found in /usr/lib64/dtrace/version/procfs.d. The definition of the lwpsinfo_t structure is as follows:

typedef struct lwpsinfo {       
        int pr_flag;                    /* lwp flags (DEPRECATED) */
        int pr_lwpid;                   /* lwp id */
        uintptr_t pr_addr;              /* internal address of lwp */
        uintptr_t pr_wchan;             /* wait addr for sleeping lwp */
        char pr_stype;                  /* sync event type */
        char pr_state;                  /* numeric lwp state */
        char pr_sname;                  /* printable char for pr_state */
        char pr_nice;                   /* nice for cpu usage */
        short pr_syscall;               /* syscall number */
        char pr_oldpri;                 /* priority */
        char pr_cpu;                    /* CPU usage */
        int pr_pri;                     /* priority */
        ushort_t pr_pctcpu;             /* % of recent cpu time */
        ushort_t pr_pad;
        timestruc_t pr_start;           /* lwp start time */
        timestruc_t pr_time;            /* usr+sys cpu time */
        char pr_clname[8];              /* scheduling class name */
        char pr_name[16];               /* name */
        processorid_t pr_onpro;         /* processor last ran on */
        processorid_t pr_bindpro;       /* processor bound to */
        psetid_t pr_bindpset;           /* processor set */
        int pr_lgrp;                    /* lwp home lgroup */
        int pr_filler[4];

} lwpsinfo_t;

Note:

Lightweight processes don't exist in Linux. Rather, in Oracle Linux, processes and threads are 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.

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

In Oracle Linux, the pr_stype field is unsupported, and hence is always 0.

The following table describes the values that pr_state can take, including the corresponding character values for pr_sname.

Table 8-5 pr_state Values

pr_state Value pr_sname Value Description

SRUN (2)

R

The thread is runnable or is 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 because of 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.

psinfo_t

Several proc probes have an argument of type psinfo_t. Detailed information about this data structure can be found in /usr/lib64/dtrace/version/procfs.d. The definition of the psinfo_t structure, is as follows:

typedef struct psinfo {
        int pr_flag;                    /* process flags (DEPRECATED) */
        int pr_nlwp;                    /* number of active lwps (Linux: 1) */
        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;                 /* size of process image (in KB) */
        size_t pr_rssize;               /* resident set sie (in KB) */
        size_t pr_pad1;
        struct tty_struct *pr_ttydev;   /* controlling tty (or -1) */
        ushort_t pr_pctcpu;             /* % of recent cpu time used */
        ushort_t pr_pctmem;             /* % of recent memory used */
        timestruc_t pr_start;           /* process start time */
        timestruc_t pr_time;            /* usr+sys cpu time for process */
        timestruc_t pr_ctime;           /* usr+sys cpu time for children */
        char pr_fname[16];              /* name of exec'd file */
        char pr_psargs[80];             /* initial chars of arg list */
        int pr_wstat;                   /* if zombie, wait() status */
        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 */
        char pr_pad2[3];
        taskid_t pr_taskid;             /* task id */
        dprojid_t pr_projid;            /* project id */
        int pr_nzomb;                   /* number of zombie lwps (Linux: 0) */
        poolid_t pr_poolid;             /* pool id */
        zoneid_t pr_zoneid;             /* zone id */
        id_t pr_contract;               /* process contract */
        int pr_filler[1];
        lwpsinfo_t pr_lwp;

} psinfo_t;

Note:

Lightweight processes don't exist in Linux. In Oracle Linux, processes and threads are 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.

proc Examples

The following examples illustrate the use of the probes that are published by the proc provider.

exec, exec-success and exec-failure

The following example shows how you can use the exec, exec-success and exec-failure probes to easily determine which programs are being run, and by which parent process. Type the following D source code and save it in a file named whoexec.d:

#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 results in output similar to the following:

WHO                  WHAT                 COUNT
bash                 date                 1
bash                 grep                 1
bash                 ssh                  1
bash                 wc                   1
bash                 ls                   2
bash                 sed                  2
...

start and exit Probes

To determine how long programs are running, from creation to termination, you can enable the start and exit probes, as shown in the following example. Save it in a file named progtime.d:

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

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

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

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

signal-send

The following example shows how you can use the signal-send probe to determine the sending and receiving of process associated with any signal. Type the following D source code and save it in a file named sig.d:

#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:

              SENDER            RECIPIENT          SIG COUNT
       kworker/u16:7               dtrace            2 1
       kworker/u16:7                 sudo            2 1
           swapper/2             sssd_kcm           34 1
           swapper/6             pmlogger           14 1

proc Stability

The proc provider uses DTrace's stability mechanism to describe its stabilities. These values are listed 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