Go to main content

Oracle® Solaris 11.3 DTrace (Dynamic Tracing) Guide

Exit Print View

Updated: July 2018
 
 

sdt Provider

The Statically Defined Tracing (SDT) provider creates probes at sites that a software programmer has formally designated. The SDT mechanism allows programmers to consciously choose locations of interest to users of DTrace and to convey some semantic knowledge about each location through the probe name. The Oracle Solaris kernel has defined a handful of SDT probes. DTrace also provides a mechanism for user application developers to define static probes. For more information, see Statically Defined Tracing for User Applications.

sdt Probes

The SDT probes defined by the Oracle Solaris kernel are listed in the following table. The name stability and data stability of these probes are both Private because their description here thus reflects the kernel's implementation and should not be inferred to be an interface commitment. For more information about the DTrace stability mechanism, see DTrace Stability Mechanisms.

Table 58  List of SDT Probes
Probe
Description
arg0
callout-start
Fires immediately before executing a callout (see <sys/callo.h>). Callouts are executed by periodic system clock, and represent the implementation for timeout.
Pointer to the callout_t (see <sys/callo.h>) corresponding to the callout to be executed.
callout-end
Fires immediately after executing a callout (see <sys/callo.h>).
Pointer to the callout_t (see <sys/callo.h>) corresponding to the callout just executed.
interrupt-start
Fires immediately before calling into a device's interrupt handler.
Pointer to the dev_info structure (see <sys/ddi_impldefs.h>) corresponding to the interrupting device.
interrupt-complete
Fires immediately after returning from a device's interrupt handler.
Pointer to dev_info structure (see <sys/ddi_impldefs.h>) corresponding to the interrupting device.

sdt Examples

The following example is a script to observe callout behavior on a per-second basis:

#pragma D option quiet

sdt:::callout-start
{
        @callouts[((callout_t *)arg0)->c_func] = count();
}

tick-1sec
{
        printa("%40a %10@d\n", @callouts);
        clear(@callouts);
}

Running this example reveals the frequent users of timeout in the system, as shown in the following output:

# dtrace -s ./callout.d
                            TS`ts_update          1
              uhci`uhci_cmd_timeout_hdlr          3
                          genunix`setrun          5
                     genunix`schedpaging          5
                         ata`ghd_timeout         10
 uhci`uhci_handle_root_hub_status_change        309
              ip`tcp_time_wait_collector          1
                            TS`ts_update          1
              uhci`uhci_cmd_timeout_hdlr          3
                     genunix`schedpaging          4
                          genunix`setrun          8
                         ata`ghd_timeout         10
 uhci`uhci_handle_root_hub_status_change        300
              ip`tcp_time_wait_collector          0
                        iprb`mii_portmon          1
                            TS`ts_update          1
              uhci`uhci_cmd_timeout_hdlr          3
                     genunix`schedpaging          4
                          genunix`setrun          7
                         ata`ghd_timeout         10
 uhci`uhci_handle_root_hub_status_change        300

The timeout interface only produces a single timer expiration. Consumers of timeout requiring interval timer functionality typically reinstall their timeout from their timeout handler. The following example shows this behavior:

#pragma D option quiet

sdt:::callout-start
{
        self->callout = ((callout_t *)arg0)->c_func;
}

fbt::timeout:entry
/self->callout && arg2 <= 100/
{
        /*
         * This case focusses interval timeout(9F)s that
         * are short.  Therfore, perform a linear quantization from 0 ticks to
         * 100 ticks.  The system clock's frequency - set by the variable
         * "hz" - defaults to 100, so 100 system clock ticks is one second. 
         */
        @callout[self->callout] = lquantize(arg2, 0, 100);
}

sdt:::callout-end
{
        self->callout = NULL;
}

END
{
        printa("%a\n%@d\n\n", @callout);
}

Running this script and waiting several seconds before typing Control-C results in output similar to the following example:

# dtrace -s ./interval.d
^C
genunix`schedpaging

           value  ------------- Distribution ------------- count    
              24 |                                         0        
              25 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20       
              26 |                                         0        

ata`ghd_timeout

           value  ------------- Distribution ------------- count    
               9 |                                         0        
              10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 51       
              11 |                                         0        

uhci`uhci_handle_root_hub_status_change

           value  ------------- Distribution ------------- count    
               0 |                                         0        
               1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1515     
               2 |                                         0

The output shows that uhci_handle_root_hub_status_change in the uhci driver represents the shortest interval timer on the system: it is called every system clock tick.

The interrupt-start probe can be used to understand interrupt activity. The following example shows how to quantize the time spent executing an interrupt handler by driver name:

interrupt-start
{
        self->ts = vtimestamp;
}

interrupt-complete
/self->ts/
{
        this->devi = (struct dev_info *)arg0;
        @[stringof(`devnamesp[this->devi->devi_major].dn_name),
            this->devi->devi_instance] = quantize(vtimestamp - self->ts);
}

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

# dtrace -s ./intr.d
dtrace: script './intr.d' matched 2 probes
^C
 isp                                                       0
           value  ------------- Distribution ------------- count    
            8192 |                                         0        
           16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
           32768 |                                         0        

  pcf8584                                                   0
           value  ------------- Distribution ------------- count    
              64 |                                         0        
             128 |                                         2        
             256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         157      
             512 |@@@@@@                                   31       
            1024 |                                         3        
            2048 |                                         0        

  pcf8584                                                   1
           value  ------------- Distribution ------------- count    
            2048 |                                         0        
            4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          154      
            8192 |@@@@@@@                                  37       
           16384 |                                         2        
           32768 |                                         0        

  qlc                                                       0
           value  ------------- Distribution ------------- count    
           16384 |                                         0        
           32768 |@@                                       9        
           65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      126      
          131072 |@                                        5        
          262144 |                                         2        
          524288 |                                         0        

  hme                                                       0
           value  ------------- Distribution ------------- count    
            1024 |                                         0        
            2048 |                                         6        
            4096 |                                         2        
            8192 |@@@@                                     89       
           16384 |@@@@@@@@@@@@@                            262      
           32768 |@                                        37       
           65536 |@@@@@@@                                  139      
          131072 |@@@@@@@@                                 161      
          262144 |@@@                                      73       
          524288 |                                         4        
         1048576 |                                         0        
         2097152 |                                         1        
         4194304 |                                         0        

  ohci                                                      0
           value  ------------- Distribution ------------- count    
            8192 |                                         0        
           16384 |                                         3        
           32768 |                                         1        
           65536 |@@@                                      143      
          131072 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     1368     
          262144 |                                         0 

Creating SDT Probes

If you are a device driver developer, you might be interested in creating your own SDT probes in your Oracle Solaris driver. The disabled probe effect of SDT is essentially the cost of several no-operation system instructions. You are therefore encouraged to add SDT probes to your device drivers as needed. Unless these probes negatively affect performance, you can leave them in your shipping code.

Declaring SDT Probes

SDT probes are declared using the DTRACE_PROBE, DTRACE_PROBE1, DTRACE_PROBE2, DTRACE_PROBE3 and DTRACE_PROBE4 macros from <sys/sdt.h>. The module name and function name of an SDT-based probe corresponds to the kernel module and function of the probe. The name of the probe depends on the name given in the DTRACE_PROBEn macro. If the name contains no two consecutive underbars (_), the name of the probe is as written in the macro. If the name contains any two consecutive underbars, the probe name converts the consecutive underbars to a single dash (-). For example, if a DTRACE_PROBE macro specifies transaction_start, the SDT probe will be named transaction-start. This substitution allows C code to provide macro names that are not valid C identifiers without specifying a string.

DTrace includes the kernel module name and function name as part of the tuple identifying a probe, so you do not need to include this information in the probe name to prevent name space collisions. You can use the command dtrace -l -P sdt -m module on your driver module to list the probes you have installed and the full names that will be seen by users of DTrace.

sdt Probe Arguments

The arguments for each SDT probe are the arguments specified in the corresponding DTRACE_PROBEn macro reference. The number of arguments depends on which macro was used to create the probe: DTRACE_PROBE1 specifies one argument, DTRACE_PROBE2 specifies two arguments, and so on. When declaring your SDT probes, you can minimize their disabled probe effect by not dereferencing pointers and not loading from global variables in the probe arguments. Both pointer dereferencing and global variable loading may be done safely in D actions that enable probes, so DTrace users can request these actions only when they are needed.

sdt Stability

The SDT provider uses DTrace's stability mechanism to describe its stabilities, as shown in the following table. For more information about the stability mechanism, see DTrace Stability Mechanisms.

Table 59  Stability Mechanism for the SDT provider
Element
Name stability
Data stability
Dependency class
Provider
Evolving
Evolving
ISA
Module
Private
Private
Unknown
Function
Private
Private
Unknown
Name
Private
Private
ISA
Arguments
Private
Private
ISA