Oracle® Solaris 11.2 Dynamic Tracing Guide

Exit Print View

Updated: July 2014
 
 

Process Destructive Actions

Some destructive actions are destructive only to a particular process. These actions are available to users with the dtrace_proc or dtrace_user privileges. See Chapter 14, Security for details on DTrace security privileges.

stop

void stop(void)

The stop action forces the process that fires the enabled probe to stop when it next leaves the kernel, as if stopped by a proc(4) action. The prun(1) utility may be used to resume a process that has been stopped by the stop action. The stop action can be used to stop a process at any DTrace probe point. This action can be used to capture a program in a particular state that would be difficult to achieve with a simple breakpoint, and then attach a traditional debugger like mdb(1) to the process. You can also use the gcore(1) utility to save the state of a stopped process in a core file for later analysis.

raise

void raise(int signal)

The raise action sends the specified signal to the currently running process. This action is similar to using the kill(1) command to send a process a signal. The raise action can be used to send a signal at a precise point in a process's execution.

copyout

void copyout(void *buf, uintptr_t addr, size_t nbytes)

The copyout action copies nbytes from the buffer specified by buf to the address specified by addr in the address space of the process associated with the current thread. If the user-space address does not correspond to a valid, faulted-in page in the current address space, an error will be generated.

copyoutstr

void copyoutstr(string str, uintptr_t addr, size_t maxlen)

The copyoutstr action copies the string specified by str to the address specified by addr in the address space of the process associated with the current thread. If the user-space address does not correspond to a valid, faulted-in page in the current address space, an error will be generated. The string length is limited to the value set by the strsize option. See Chapter 10, Options and Tunables for details.

system

void system(string program, ...)

The system action causes the program specified by program to be executed as if it were given to the shell as input. The program string may contain any of the printf/printa format conversions. Arguments must be specified that match the format conversions. Refer to Chapter 6, Output Formatting for details on valid format conversions.

The following example runs the date(1) command once per second:

# dtrace -wqn tick-1sec'{system("date")}'
 Tue Jul 20 11:56:26 CDT 2004
 Tue Jul 20 11:56:27 CDT 2004
 Tue Jul 20 11:56:28 CDT 2004
 Tue Jul 20 11:56:29 CDT 2004
 Tue Jul 20 11:56:30 CDT 2004

The following example shows a more elaborate use of the action, using printf conversions in the program string along with traditional filtering tools like pipes:

#pragma D option destructive
#pragma D option quiet

proc:::signal-send
/args[2] == SIGINT/
{
        printf("SIGINT sent to %s by ", args[1]->pr_fname);
        system("getent passwd %d | cut -d: -f5", uid);
}

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

# ./whosend.d
SIGINT sent to MozillaFirebird- by Bryan Cantrill
SIGINT sent to run-mozilla.sh by Bryan Cantrill
^C
SIGINT sent to dtrace by Bryan Cantrill

The execution of the specified command does not occur in the context of the firing probe. It occurs when the buffer containing the details of the system action are processed at user-level. How and when this processing occurs depends on the buffering policy, described in Chapter 5, Buffers and Buffering. With the default buffering policy, the buffer processing rate is specified by the switchrate option. You can see the delay inherent in system if you explicitly tune the switchrate higher than its one-second default, as shown in the following example:

#pragma D option quiet
#pragma D option destructive
#pragma D option switchrate=5sec

tick-1sec
/n++ < 5/
{
        printf("walltime  : %Y\n", walltimestamp);
        printf("date      : ");
        system("date");
        printf("\n");
}

tick-1sec
/n == 5/
{
        exit(0);
}

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

# dtrace -s ./time.d
 walltime  : 2004 Jul 20 13:26:30
date      : Tue Jul 20 13:26:35 CDT 2004

walltime  : 2004 Jul 20 13:26:31
date      : Tue Jul 20 13:26:35 CDT 2004

walltime  : 2004 Jul 20 13:26:32
date      : Tue Jul 20 13:26:35 CDT 2004

walltime  : 2004 Jul 20 13:26:33
date      : Tue Jul 20 13:26:35 CDT 2004

walltime  : 2004 Jul 20 13:26:34
date      : Tue Jul 20 13:26:35 CDT 2004

Notice that the walltime values differ, but the date values are identical. This result reflects the fact that the execution of the date(1) command occurred only when the buffer was processed, not when the system action was recorded.