1.1 Getting Started With DTrace

Note

Most uses of DTrace require root privileges.

Prior to installing the dtrace_utils package, ensure that you are subscribed to the ULN channel that corresponds to the UEK kernel that you are running. For example, if you are running Oracle Linux 7 with UEK R5, the dtrace_utils package is available in the ol7_UEKR5 channel. For more information about subscribing to channels on ULN, see the Oracle Linux Unbreakable Linux Network Guide.

For information about updating your Oracle Linux release, see the documentation at https://docs.oracle.com/cd/E52668_01/.

For information about updating your UEK release, see the documentation at https://docs.oracle.com/cd/E93554_01/index.html.

Install the dtrace-utils package:

# yum install dtrace-utils

If you want to implement a libdtrace consumer:

# yum install dtrace-utils-devel

If you want to develop a DTrace provider:

# yum install dtrace-modules-provider-headers

To confirm that dtrace is properly installed on your system and that you have all of the required privileges, use the dtrace -l command. Running this command should load any of the required kernel modules and the output should indicate any available probes.

Note

The dtrace-utils package installs dtrace in /usr/sbin/dtrace. Make sure your path detects this path instead of the similarly named utility that is located in /usr/bin/dtrace, which is installed by the systemtap-sdt-devel package.

A provider is a set of probes with a particular kind of instrumentation.

Note

To use a provider's probes, the kernel module that supports that provider must be loaded. Typically, dtrace automatically handles this for you. Upon first use, it will load the dtrace module and all of the modules that are listed in /etc/dtrace-modules, which the system administrator can edit.

In some cases, the kernel module that supports the desired provider must be loaded manually, for example:

# more /etc/dtrace-modules
sdt
systrace
profile
fasttrap
# modprobe sdt
# modprobe systrace
# modprobe profile
# modprobe fasttrap

These required modules are different from the modules, if any, that are instrumented by the provider's probes and are found in the dtrace -l output. For example, while the module that is required to support proc probes is sdt, the module that these probes instrument is vmlinux, as shown in the following output:

# dtrace -l -P proc
   ID   PROVIDER    MODULE          FUNCTION NAME
  197       proc   vmlinux          _do_fork lwp-create
  198       proc   vmlinux          _do_fork create
  225       proc   vmlinux           do_exit lwp-exit
  226       proc   vmlinux           do_exit exit
  275       proc   vmlinux   do_sigtimedwait signal-clear
...

You dynamically assign actions to be taken at probes, which can be runtime events or source-code locations. Every probe in DTrace has two names: a unique integer ID, which is assigned as the probes are loaded, and a human-readable string name. You can start learning about DTrace by building some very simple requests that use the probe named BEGIN. The BEGIN probe fires once each time you start a new tracing request.

Use the dtrace command with the -n option to enable a probe by specifying its name:

# dtrace -n BEGIN
dtrace: description 'BEGIN' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0      1                           :BEGIN 
^C
#

The default output of the previous example displays the following information: the probes that were matched, column headers, and then one row each time a probe fires. The default per row is the CPU where the probe fired and information about which probe fired. DTrace remains paused, waiting for other probes to fire. To exit, press Ctrl-C.

You can construct DTrace requests by using arbitrary numbers of probes and actions. For example, create a simple request using two probes by adding the END probe to the command shown in the previous example. The END probe fires once when tracing is completed.

Type the following command, and then press Ctrl-C in your shell again, after you see the line of output for the BEGIN probe:

# dtrace -n BEGIN -n END 
dtrace: description 'BEGIN' matched 1 probe
dtrace: description 'END' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0      1                           :BEGIN 
^C
  1      2                             :END

Pressing Ctrl-C to exit dtrace triggers the END probe. The dtrace command reports this probe firing before exiting.

In addition to constructing DTrace experiments on the command line, you can also write DTrace experiments in text files by using the D programming language.

In a text editor, create a new file named hello.d and type your first D program:

BEGIN
{
  trace("hello, world");
  exit(0);
}

After you save the program, you can run it by using the dtrace -s command, as shown in the following example:

# dtrace -s hello.d
dtrace: script 'hello.d' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0      1                           :BEGIN   hello, world   
#

The dtrace command printed the same output as the previous example, followed by the text, ”hello, world”. However, unlike the previous example, you did not have to wait and then press Ctrl-C. These changes were the result of the actions that you specified for the BEGIN probe in hello.d.

To understand what happened, let us explore the structure of your D program in more detail.

  • Each D program consists of a series of clauses, and each clause describes one or more probes to enable, as well as an optional set of actions to perform when the probes fires.

  • The actions are listed as a series of statements that are enclosed in braces ({}) that follow the probe name. Each statement ends with a semicolon (;).

  • The first statement uses the trace() function to indicate that DTrace should record the specified argument, the string, ”hello, world”, when the BEGIN probe fires and then print it out.

  • The second statement uses the exit() function to indicate that DTrace should cease tracing and exit the dtrace command.

DTrace provides a set of useful functions such as trace() and exit() for you to call in your D programs.

To call a function, you specify its name, followed by a parenthesized list of arguments. See Chapter 4, Actions and Subroutines for the complete set of D functions.

If you are familiar with the C programming language, you probably have noticed that DTrace's D programming language is very similar to C. Indeed, D is derived from a large subset of C, combined with a special set of functions and variables to help make tracing easy. These features are described in more detail in subsequent chapters. If you have written a C program previously, you should be able to immediately transfer most of your knowledge to building tracing programs in D. If you have never written a C program, learning D is still relatively easy. By the end of this chapter, you will understand all of the syntax. First, let us take a step back from language rules and learn more about how DTrace works. Then, later in this guide, you will learn how to build more interesting D programs.