Chapter 4 Actions and Subroutines

You use D function calls such as trace and printf to invoke two different kinds of services that are provided by DTrace: actions and subroutines. Actions trace data or modify a state that is external to DTrace, while subroutines affect only the internal DTrace state.

This chapter defines DTrace actions and subroutines and also describes their syntax and semantics.

4.1 Action Functions

Action functions enable your DTrace programs to interact with the system outside of DTrace. The most common actions record data to a DTrace buffer. Other actions are available, such as stopping the current process, raising a specific signal on the current process, and ceasing tracing altogether. Some of these actions are destructive, in that they change the system, albeit in a well-defined way. These actions may only be used if destructive actions have been explicitly enabled. By default, data recording actions record data to the principal buffer. For more information about the principal buffer and buffer policies, see Chapter 5, Buffers and Buffering.

4.1.1 Default Action

A clause can contain any number of actions and variable manipulations. If a clause is left empty, the default action is taken. The default action is to trace the enabled probe identifier (EPID) to the principal buffer. For more information about epid, see Section 2.9.5, “Built-In Variables”. From the EPID, the dtrace command outputs the following information: CPU, probe ID, probe function, and probe name.

The default action facilitates a simple use of the dtrace command. For example, running the following command enables all of the probes in the vmlinux module with the default action:

# dtrace -m vmlinux

The preceding command might produce output similar to the following:

# dtrace -m vmlinux
dtrace: description 'vmlinux' matched 35 probes
CPU     ID                    FUNCTION:NAME
  0     42                 __schedule:sleep 
  0     34             dequeue_task:dequeue 
  0     40               __schedule:off-cpu 
  0     23        finish_task_switch:on-cpu 
  0     24             enqueue_task:enqueue 
  0     41               __schedule:preempt 
  0     40               __schedule:off-cpu 
  0     23        finish_task_switch:on-cpu 
  0     11        update_process_times:tick 
  0     42                 __schedule:sleep 
  0     34             dequeue_task:dequeue 
  0     40               __schedule:off-cpu 
  0     23        finish_task_switch:on-cpu 
  0     24             enqueue_task:enqueue 
  0     41               __schedule:preempt 
  0     40               __schedule:off-cpu 
  0     23        finish_task_switch:on-cpu 
  0     11        update_process_times:tick 
  0     12            try_to_wake_up:wakeup 
  0     42                 __schedule:sleep 
...

4.1.2 Data Recording Actions

Data recording actions are the core DTrace actions. Each of these actions records data to the principal buffer by default, but each action can also be used to record data to speculative buffers. See Chapter 5, Buffers and Buffering and Chapter 7, Speculative Tracing for more details on the principal buffer and speculative buffers.

The following descriptions refer only to the directed buffer, indicating that data is recorded either to the principal buffer or to a speculative buffer if the action follows a speculate.

4.1.2.1 freopen

void freopen(string format, ...)

The freopen action changes the file that is associated with stdout to the file that is specified by the arguments in printf fashion.

If the "" string is used, the output is again restored to stdout.

Caution

The freopen action is not only data-recording but also destructive, because you can use it to overwrite arbitrary files.

4.1.2.2 ftruncate

void ftruncate(void)

The ftruncate action truncates the output stream on stdout.

4.1.2.3 func

_symaddr func(uintptr_t address)

The func action prints the symbol that corresponds to a specified kernel-space address. For example, func((uintptr_t) (&vmlinux`max_pfn)) causes vmlinux`max_pfn to be printed. The func action is an alias for sym.

4.1.2.4 mod

_symaddr mod(uintptr_t address)

The mod action prints the name of the module that corresponds to a specified kernel-space address. For example, mod((uintptr_t) (&vmlinux`max_pfn)) prints vmlinux.

4.1.2.5 printa

void printa(aggregation)
void printa(string format, aggregation)

The printa action enables you to display and format aggregations. See Chapter 3, Aggregations for more details. If format is not specified, printa traces only a directive to the DTrace consumer for which the specified aggregation should be processed and is displayed using the default format. If format is specified, the aggregation is formatted. See Section 6.2, “printa Action” for a detailed description of the printa format string.

When printa traces only a directive that the aggregation should be processed by the DTrace consumer, it does not process the aggregation in the kernel. Therefore, the time between the tracing of the printa directive and the actual processing of the directive depends on factors that affect buffer processing, which include the following: the aggregation rate, the buffering policy (and if the buffering policy is switching), and the rate at which buffers are switched. See Chapter 3, Aggregations and Chapter 5, Buffers and Buffering for detailed descriptions.

4.1.2.6 printf

void printf(string format, ...)

Like trace, the printf action traces D expressions, but printf enables elaborate printf-style formatting. The parameters consist of a format string, followed by a variable number of arguments. By default, the arguments are traced to the directed buffer. The arguments are later formatted for output by the dtrace command, according to the specified format string, for example:

printf("execname is %s; priority is %d", execname, curlwpsinfo->pr_pri);

For more information, see Section 6.1, “printf Action”.

4.1.2.7 stack

stack stack(int nframes)
stack stack(void)

The stack action records a kernel stack trace to the directed buffer. The kernel stack is nframes in depth. If nframes is not specified, the number of stack frames recorded is the number that is specified by the stackframes option. The dtrace command reports frames, either up to the root frame or until the nframes limit has been reached, whichever comes first:

# dtrace -n gettimeofday:entry'{stack()}'
dtrace: description 'gettimeofday:entry' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0    196               gettimeofday:entry 
              vmlinux`pollwake
              vmlinux`dtrace_stacktrace+0x30
              vmlinux`__brk_limit+0x1e1832d7
              vmlinux`__brk_limit+0x1e1913a1
              vmlinux`pollwake
              vmlinux`do_gettimeofday+0x1a
              vmlinux`ktime_get_ts+0xad
              vmlinux`systrace_syscall+0xde
              vmlinux`audit_syscall_entry+0x1d7
              vmlinux`system_call_fastpath+0x16

  0    196               gettimeofday:entry 
              vmlinux`dtrace_stacktrace+0x30
              vmlinux`__brk_limit+0x1e1832d7
              vmlinux`__brk_limit+0x1e1913a1
              vmlinux`security_file_permission+0x8b
              vmlinux`systrace_syscall+0xde
              vmlinux`audit_syscall_entry+0x1d7
              vmlinux`system_call_fastpath+0x16

...

The stack action, having a non-void return value, can also be used as the key to an aggregation, for example:

# dtrace -n execve:entry'{@[stack()] = count()}'
dtrace: description 'execve:entry' matched 1 probe
^C


              vmlinux`dtrace_stacktrace+0x30
              vmlinux`__brk_limit+0x1e1832d7
              vmlinux`__brk_limit+0x1e1913a1
              vmlinux`dtrace_execve+0xcd
              vmlinux`audit_syscall_entry+0x1d7
              vmlinux`dtrace_stub_execve+0x6c
                2

              vmlinux`dtrace_stacktrace+0x30
              vmlinux`__brk_limit+0x1e1832d7
              vmlinux`__brk_limit+0x1e1913a1
              vmlinux`do_sigaction+0x13a
              vmlinux`dtrace_execve+0xcd
              vmlinux`audit_syscall_entry+0x1d7
              vmlinux`dtrace_stub_execve+0x6c
               13

...

4.1.2.8 sym

_symaddr sym(uintptr_t address)

The sym action prints the symbol that corresponds to a specified kernel-space address. For example, sym((uintptr_t) (&vmlinux`max_pfn)) causes vmlinux`max_pfn to be printed. The sym action is an alias for func.

4.1.2.9 trace

void trace(expression)

The trace action is the most basic action. This action takes a D expression as its argument and then traces the result to the directed buffer. The following statements are examples of trace actions:

trace(execname);
trace(curlwpsinfo->pr_pri);
trace(timestamp / 1000);
trace(‘lbolt);
trace("somehow managed to get here");

If the trace action is used on a buffer, the output format depends on the data type. If the dtrace command determines that the data is like an ASCII string, it prints it as text and terminates the output with a null character (0). When dtrace decides that the data is most likely binary, it prints it in hexadecimal format, for example:

0      342                      write:entry
             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
         0: c0 de 09 c2 4a e8 27 54 dc f8 9f f1 9a 20 4b d1  ....J.’T..... K.
        10: 9c 7a 7a 85 1b 03 0a fb 3a 81 8a 1b 25 35 b3 9a  .zz.....:...%5..
        20: f1 7d e6 2b 66 6d 1c 11 f8 eb 40 7f 65 9a 25 f8  .}.+fm....@.e.%.
        30: c8 68 87 b2 6f 48 a2 a5 f3 a2 1f 46 ab 3d f9 d2  .h..oH.....F.=..
        40: 3d b8 4c c0 41 3c f7 3c cd 18 ad 0d 0d d3 1a 90  =.L.A<.<........

You can force the trace action to always use the binary format by specifying the rawbytes option.

4.1.2.10 tracemem

void tracemem(address, size_t nbytes)
void tracemem(address, size_t nbytes, size_t dbytes)

The tracemem action takes a D expression as its first argument, address, and a constant as its second argument, nbytes. The tracemem action copies the memory from the address specified by address into the directed buffer for the length specified by nbytes. If only two arguments are provided, dtrace dumps the entire contents of the buffer.

In the second format, the tracemem action takes an additional, third argument, dbytes, which is a D expression that is computed dynamically. The result is used to limit the number of bytes that are displayed. If the result is less than zero or greater than nbytes, the result is ignored and tracemem behaves as though it is called by using the two-argument form. Otherwise, dtrace dumps only the dbytes bytes of the directed buffer.

4.1.2.11 ustack

Note

If you want to perform symbol lookup in a stripped executable, you must specify the --export-dynamic option when linking the program. This option causes the linker to add all symbols to the dynamic symbol table, which is the set of symbols that is visible from dynamic objects at run time. If you use gcc to link the objects, specify the option as -Wl,--export-dynamic to pass the correct option to the linker.

Note also that f you want to look up symbols in shared libraries or unstripped executables, the --export-dynamic option is not required.

DTrace supports the use of the ustack action with both 32-bit and 64-bit binaries, for example:

stack ustack(int nframes, int strsize) 
stack ustack(int nframes)
stack ustack(void)

The ustack action records a user stack trace to the directed buffer. The user stack is nframes in depth. If nframes is not specified, the number of stack frames that is recorded is the number specified by the ustackframes option. While ustack is able to determine the address of the calling frames when the probe fires, the stack frames are not translated into symbols until the ustack action is processed at user level by the DTrace consumer. If strsize is specified and is non-zero, ustack allocates the specified amount of string space and then uses it to perform address-to-symbol translation directly from the kernel. Such direct user symbol translation is used only with stacktrace helpers that support this usage with DTrace. If such frames cannot be translated, the frames appear only as hexadecimal addresses.

The following example traces a stack with no address-to-symbol translation:

# dtrace -n syscall::write:entry'/pid == $target/{ustack(); exit(0)}' -c "./mytestprog -v"
dtrace: description 'syscall::write:entry' matched 1 probe
mytestprog (Version 1.0)
CPU     ID                    FUNCTION:NAME
  2      6                      write:entry 
              mytestprog`printver+0x2f
              mytestprog`0x401338
              mytestprog`main+0xc7
              mytestprog`0x401338
              libc.so.6`__libc_start_main+0xfd
              mytestprog`main
              mytestprog`0x400ad0
              mytestprog`__libc_csu_init
              mytestprog`0x400ad0
              mytestprog`0x400af9

The ustack symbol translation occurs after the stack data is recorded. Therefore, the corresponding user process might exit before symbol translation can be performed, making stack frame translation impossible. If the user process exits before symbol translation is performed, dtrace outputs a warning message, followed by the hexadecimal stack frames.

4.1.2.12 uaddr

DTrace supports the use of the uaddr action with both 32-bit and 64-bit binaries.

_usymaddr uaddr(uintptr_t address)

The uaddr action prints the symbol for a specified address, including hexadecimal offset, which enables the same symbol resolution that ustack provides.

4.1.2.13 usym

DTrace supports the use of the usym action with both 32-bit and 64-bit binaries.

_usymaddr usym(uintptr_t address)

The usym action prints the symbol for a specified address, which is analogous to how uaddr works, but without the hexadecimal offsets.

4.1.3 Destructive Actions

Some DTrace actions are destructive, in that they change the state of the system in some well-defined way. Destructive actions may not be used unless they have been explicitly enabled. When using dtrace, you enable destructive actions by using the -w option. If you attempt to perform destructive actions without explicitly enabling them, dtrace fails with a message similar to the following:

dtrace: failed to enable 'syscall': destructive actions not allowed

Process-destructive actions are destructive only to a particular process. Whereas, kernel-destructive actions are destructive to the entire system. Therefore, these actions must be used extremely carefully, as such actions affect every process on the system and any other system, implicitly or explicitly, depending upon the affected system's network services.

The following information pertains to both process-destructive and kernel-destructive actions.

4.1.3.1 copyout (Process-Destructive)

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

The copyout action copies nbytes from the buffer that is specified by buf to the address that is specified by addr, in the address space of the process that 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 is generated.

4.1.3.2 copyoutstr (Process-Destructive)

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

The copyoutstr action copies the string tha tis specified by str to the address that is 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 is generated. Note that the string length is limited to the value that is set by the strsize option. See Chapter 10, Options and Tunables.

4.1.3.3 raise (Process-Destructive)

void raise(int signal)

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

4.1.3.4 stop (Process-Destructive)

void stop(void)

The stop action forces the process that is firing the enabled probe to stop when it next leaves the kernel, as if stopped by a proc 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 such as gdb to the process. You can also use the gcore utility to save the state of a stopped process in a core file for later analysis.

4.1.3.5 system (Process-Destructive)

void system(string program, ...)

The system action causes the specified program to be executed as though given to the shell as input. The program string can contain any of the printf or printa format conversions. Arguments that match the format conversions must be specified. See Chapter 6, Output Formatting for details on valid format conversions.

The following example runs the date command once per second:

# dtrace -wqn tick-1sec'{system("date")}'
Tue Oct 16 10:21:34 BST 2012
Tue Oct 16 10:21:35 BST 2012
Tue Oct 16 10:21:36 BST 2012
^C
#

The following example shows a more elaborate use of the action by using printf conversions in the program string, along with traditional filtering tools such as pipes. Type the following source code and save it in a file named whosend.d:

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

# dtrace -s whosend.d
SIGINT sent to top by root
SIGINT sent to bash by root
SIGINT sent to bash by A Nother
^C
SIGINT sent to dtrace by root

The execution of the specified command does not occur in the context of the firing probe. Rather, 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, as 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 that is inherent in system if you explicitly tune the switchrate higher than its one-second default, as shown in the following example. Save it in a file named time.d:

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

# dtrace -s time.d
walltime : 2012 Oct 16 10:26:07
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:08
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:09
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:10
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:11
date : Tue Oct 16 10:26:11 BST 2012

In the previous output, notice that the walltime values differ, but the date values are identical. This result reflects the fact that the execution of the date command occurred when the buffer was processed, not when the system action was recorded.

4.1.3.6 chill (Kernel-Destructive)

void chill(int nanoseconds)

The chill action causes DTrace to spin for the specified number of nanoseconds. This action is primarily useful for exploring problems that might be timing related. For example, you can use this action to open race condition windows or bring periodic events into or out of phase with one another. Because interrupts are disabled while in DTrace probe context, any use of the chill action results in an interrupt, scheduling, or dispatch latency. Therefore, chill can cause unexpected systemic effects and therefore should not be used indiscriminately. Because system activity relies on periodic interrupt handling, DTrace refuses to execute the chill action for more than 500 milliseconds out of each one-second interval on any given CPU. If the maximum chill interval is exceeded, DTrace reports an illegal operation error:

# dtrace -w -n syscall::openat:entry'{chill(500000001)}'
dtrace: allowing destructive actions
dtrace: description 'syscall::openat:entry' matched 1 probe 
dtrace: 57 errors
CPU     ID                    FUNCTION:NAME 
dtrace: error on enabled probe ID 1 (ID 14: syscall::openat:entry): \
illegal operation in action #1

This limit is enforced even if the time is spread across multiple calls to chill or multiple DTrace consumers of a single probe. For example, the same error would be generated by running the following command:

# dtrace -w -n syscall::openat:entry'{chill(250000000); chill(250000001);}'

4.1.3.7 panic (Kernel-Destructive)

void panic(void)

When triggered, the panic action causes a kernel panic. This action should be used to force a system crash dump at a time of interest. You can use this action along with ring buffering to understand a problem. For more information, see Chapter 5, Buffers and Buffering . When the panic action is used, a panic message appears denoting the probe that is causing the panic. rsyslogd also emits a message upon reboot. The message buffer of the crash dump contains the probe and event control block (ECB) that is responsible for the panic action.

4.1.4 Special Actions

The following are special actions that are not data recording actions or destructive actions.

4.1.4.1 Speculative Actions

The actions associated with speculative tracing are speculate, commit, and discard. These actions are described in more detail in Chapter 7, Speculative Tracing.

4.1.4.2 exit

void exit(int status)

The exit action is used to immediately stop tracing and inform the DTrace consumer that it should do the following: cease tracing, perform any final processing, and call exit() with the specified status value. Because exit returns a status to user level, it is considered a data recording action, However, unlike other data storing actions, exit cannot be speculatively traced. The exit action causes the DTrace consumer to exit regardless of buffer policy. Note that because exit is a data recording action, it can be dropped.

When exit is called, only those DTrace actions that are already in progress on other CPUs are completed. No new actions occur on any CPU. The only exception to this rule is the processing of the END probe, which is called after the DTrace consumer has processed the exit action, and indicates that tracing should stop.

4.1.4.3 setopt

void setopt(const char *opt_name)
void setopt(const char *opt_name, const char *opt_value)

The setopt action enables you to specify a DTrace option dynamically, for example:

setopt("quiet");
setopt("bufsize", "50m");
setopt("aggrate", "2hz");

4.2 Subroutine Functions

Subroutine functions differ from actions because they generally only affect the internal DTrace state. Therefore, no destructive subroutines exist. Also, subroutines never trace data into buffers. Many subroutines have analogs in the application programming interfaces. See the Section 3 manual pages for more details.

A number of these subroutines require temporary buffers, which persist only for duration of the clause. Pre-allocated scratch memory is used for such buffers.

4.2.1 alloca

void *alloca(size_t size)

The alloca function allocates size bytes out of scratch memory, and returns a pointer to the allocated memory. The returned pointer is guaranteed to have 8–byte alignment. Scratch memory is only valid for the duration of a clause. Memory that is allocated with alloca is deallocated when the clause completes. If insufficient scratch memory is available, no memory is allocated and an error is generated.

4.2.2 basename

string basename(char *str)

The basename function creates a string that consists of a copy of the specified string, but excludes any prefix that ends in /, such as a directory path. The returned string is allocated out of scratch memory, and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, basename does not execute and an error is generated.

4.2.3 bcopy

void bcopy(void *src, void *dest, size_t size)

The bcopy function copies size bytes from the memory that is pointed to by src to the memory that is pointed to by dest. All of the source memory must lie outside of scratch memory, and all of the destination memory must lie within it. If these conditions are not met, no copying takes place and an error is generated.

4.2.4 cleanpath

string cleanpath(char *str)

The cleanpath function creates a string consisting of a copy of the path indicated by str, but with certain redundant elements eliminated. In particular, /./ elements in the path are removed, and /../ elements are collapsed. The collapsing of /../ elements in the path occurs without regard to symbolic links. Therefore, it is possible that cleanpath could take a valid path and return a shorter, invalid path.

For example, if str were “/foo/../bar” and /foo were a symbolic link to /net/foo/export, cleanpath would return the string “/bar”, even though bar might only exist in /net/foo and not in /. This limitation is due to the fact that cleanpath is called in the context of a firing probe, where full symbolic link resolution of arbitrary names is not possible. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, cleanpath does not execute and an error is generated.

4.2.5 copyin

void *copyin(uintptr_t addr, size_t size)

The copyin function copies the specified size in bytes from the specified user address (addr) into a DTrace scratch buffer and returns the address of this buffer. The user address is interpreted as an address in the space of the process that is associated with the current thread. The resulting buffer pointer is guaranteed to have 8-byte alignment. The address in question must correspond to a faulted-in page in the current process. If the address does not correspond to a faulted-in page, or if insufficient scratch memory is available, NULL is returned and an error is generated.

4.2.6 copyinstr

string copyinstr(uintptr_t addr)
string copyinstr(uintptr_t addr, size_t maxlen)

The copyinstr function copies a null-terminated C string from the specified user address (addr) into a DTrace scratch buffer and returns the address of this buffer. The user address is interpreted as an address in the space of the process that is associated with the current thread. The maxlen parameter, if specified, sets a limit on the number of bytes past addr that are examined (the resulting string is always null-terminated). The resulting string's length is limited to the value set by the strsize option. See Chapter 10, Options and Tunables for details. As with the copyin function, the specified address must correspond to a faulted-in page in the current process. If the address does not correspond to a faulted-in page, or if insufficient scratch memory is available, NULL is returned and an error is generated.

4.2.7 copyinto

void copyinto(uintptr_t addr, size_t size, void *dest)

The copyinto function copies the specified size in bytes from the specified user address (addr) into the DTrace scratch buffer that is specified by dest. The user address is interpreted as an address in the space of the process that is associated with the current thread. The address in question must correspond to a faulted-in page in the current process. If the address does not correspond to a faulted-in page, or if any of the destination memory lies outside of scratch memory, no copying takes place and an error is generated.

4.2.8 d_path

string d_path(struct path *ptr)

The d_path function creates a string containing the absolute pathname of the struct path that is pointed to by ptr. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, d_path does not execute and an error is generated.

4.2.9 dirname

string dirname(char *str)

The dirname function creates a string that consists of all but the last level of the pathname that is specified by str. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, dirname does not execute and an error is generated.

4.2.10 getmajor

dev_t getmajor(dev_t dev)

The getmajor function returns the major device number for the device that is specified by dev.

4.2.11 getminor

dev_t getminor(dev_t dev)

The getminor function returns the minor device number for the device that is specified by dev.

4.2.12 htonl

uint32_t htonl(uint32_t hostlong)

The htonl function converts hostlong from host-byte order to network-byte order.

4.2.13 htonll

uint64_t htonll(uint64_t hostlonglong)

The htonll function converts hostlonglong from host-byte order to network-byte order.

4.2.14 htons

uint16_t htons(uint16_t hostshort)

The htons function converts hostshort from host-byte order to network-byte order.

4.2.15 index

int index(const char *s, const char *subs)
int index(const char *s, const char *subs, int start)

The index function locates the position of the first occurrence of the substring (subs) in the s string, starting at the optional position start. If the specified value of start is less than 0, it is implicitly set to 0. If s is an empty string, index returns 0. If no match is found for subs in s, index returns 1.

4.2.16 inet_ntoa

string inet_ntoa(ipaddr_t *addr)

The inet_ntoa function takes a pointer addr to an IPv4 address and returns it as a dotted, quad decimal string. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, inet_ntoa does not execute and an error is generated.

4.2.17 inet_ntoa6

string inet_ntoa6(in6_addr_t *addr)

The inet_ntoa6 function takes a pointer addr to an IPv6 address and returns it as an RFC 1884 convention 2 string, with lowercase hexadecimal digits. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, inet_ntoa6 does not execute and an error is generated.

4.2.18 inet_ntop

string inet_ntop(int af, void *addr)

The inet_ntop function takes a pointer addr to an IP address and returns a string version that depends on the provided address family. Supported address families are AF_INET and AF_INET6, both of which are defined for use in D programs. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, inet_ntop does not execute and an error is generated.

4.2.19 lltostr

string lltostr(int64_t longlong)

The lltostr function converts longlong to a string. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, lltostr does not execute and an error is generated.

4.2.20 mutex_owned

int mutex_owned(kmutex_t *mutex)

The mutex_owned function returns non-zero if the calling thread currently holds the specified kernel mutex, or zero otherwise.

4.2.21 mutex_owner

kthread_t *mutex_owner(kmutex_t *mutex)

The mutex_owner function returns the thread pointer of the current owner of the specified adaptive kernel mutex. mutex_owner returns NULL if the specified adaptive mutex is currently unowned or if the specified mutex is a spin mutex.

4.2.22 mutex_type_adaptive

int mutex_type_adaptive(kmutex_t *mutex)

All mutexes in the Oracle Linux kernel are adaptive, so the mutex_type_adaptive function always returns 1.

4.2.23 mutex_type_spin

int mutex_type_spin(kmutex_t *mutex)

All mutexes in the Oracle Linux kernel are adaptive, so the mutex_type_spin function always returns 0.

4.2.24 ntohl

uint32_t ntohl(uint32_t netlong)

The ntohl function converts netlong from network-byte order to host-byte order.

4.2.25 ntohll

uint64_t ntohll(uint64_t netlonglong)

The ntohll function converts netlonglong from network-byte order to host-byte order.

4.2.26 ntohs

uint16_t ntohs(uint16_t netshort)

The ntohs function converts netshort from network-byte order to host-byte order.

4.2.27 progenyof

int progenyof(pid_t pid)

The progenyof function returns non-zero if the calling process (the process associated with the thread that is currently triggering the matched probe) is among the progeny of the specified process ID pid.

4.2.28 rand

int rand(void)

The rand function returns a pseudo-random integer. Because the number that is returned is a weak pseudo-random number, it therefore should not be used for any cryptographic application.

4.2.29 rindex

int rindex(const char *s, const char *subs)
int rindex(const char *s, const char *subs, int start)

The rindex function locates the position of the last occurrence of the substring subs in the string s, starting at the optional position, start. If the specified value of start is less than 0, it is implicitly set to 0. If s is an empty string, rindex returns 0. If no match is found for subs in s, rindex returns -1.

4.2.30 rw_iswriter

int rw_iswriter(krwlock_t *rwlock)

The rw_iswriter function returns non-zero if the specified reader-writer lock (rwlock) is either held or desired by a writer. If the lock is held only by readers and no writer is blocked, or if the lock is not held at all, rw_iswriter returns zero.

4.2.31 rw_read_held

int rw_read_held(krwlock_t *rwlock)

The rw_read_held function returns non-zero if the specified reader-writer lock (rwlock) is currently held by a reader. If the lock is held only by writers or is not held at all, rw_read_held returns zero.

4.2.32 rw_write_held

int rw_write_held(krwlock_t *rwlock)

The rw_write_held function returns non-zero if the specified reader-writer lock (rwlock) is currently held by a writer. If the lock is held only by readers or is not held at all, rw_write_held returns zero.

4.2.33 speculation

int speculation(void)

The speculation function reserves a speculative trace buffer for use with speculate and returns an identifier for this buffer. See Chapter 7, Speculative Tracing for details.

4.2.34 strchr

string strchr(const char *s, char c)

The strchr function returns a pointer to the first occurrence of the character c in the string s. If no match is found, strstr returns 0. Note that this function does not work with wide characters or multi-byte characters.

4.2.35 strjoin

string strjoin(char *str1, char *str2)

The strjoin functon creates a string that consists of str1 concatenated with str2. The returned string is allocated out of scratch memory and is therefore valid only for the duration of the clause. If insufficient scratch memory is available, strjoin does not execute and an error is generated.

4.2.36 strlen

size_t strlen(string str)

The strlen function returns the length of the specified string str in bytes, excluding the terminating null byte.

4.2.37 strrchr

string strrchr(const char *s, char c)

The strrchr function returns a pointer to the last occurrence of the character c in the string s. If no match is found, strrstr returns 0. This function does not work with wide characters or multi-byte characters.

4.2.38 strstr

string strstr(const char *s, const char *subs)

The strstr function returns a pointer to the first occurrence of the substring subs in the string s. If s is an empty string, strstr returns a pointer to an empty string. If no match is found, strstr returns 0.

4.2.39 strtok

string strtok(const char *str, const char *delim)

The strtok function parses a string into a sequence of tokens by using delim as the delimiting string . When you initially call strtok, specify the string to be parsed in str. In each subsequent call to obtain the next token, specify str as NULL. You can specify a different delimiter for each call. The internal pointer that strtok uses to traverse str is only valid within multiple enablings of the same probe, meaning it behaves like an implicit clause-local variable. The strtok function returns NULL if there are no more tokens.

4.2.40 substr

string substr(const char *s, int index)
string substr(const char *s, int index, int length)

The substr function returns the substring of the s, string, starting at the index position. If length is specified, substr limits the substring to that length.