The data recording actions comprise the core DTrace actions. Each of these actions records data to the principal buffer by default, but each action may also be used to record data to speculative buffers. For more information about the principal buffer, see DTrace Buffers and Buffering. For more information about speculative buffers, see Speculative Tracing in DTrace. The descriptions in this section 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.
When using dtrace to build simple monitoring scripts, you can periodically clear the values in an aggregation using the clear() function. For more information, see the Clearing Aggregations.
For more information, see the Data Normalization.
void freopen(string pathname) void freopen(string format, ...)
The freopen action changes the standard output file to the file specified by pathname argument. This action is potentially destructive and needs to be activated by the –w destructive option.
"dispatch_command": #!/usr/sbin/dtrace -qw #pragma D option strsize=1024 dtrace:::BEGIN { freopen("/tmp/sqls"); } pid$target::*dispatch_command*:entry { printf("%Y-> %s \n",walltimestamp,copyinstr(arg2)); }
which gives logs like:
2009 Feb 5 08:13:43- > create table fo_bawr (i INTEGER) 2009 Feb 5 08:13:56- > create table foo_bar (is INTEGER)
The ftruncate action truncates standard output file, but does not truncate standard error file. Perform the following steps to truncate a standard error file:
Re-open stdout as stderr.
Truncate stderr.
Re-open the original stdout.
Following example displays how to truncate a standard error file.
# cat > script.d <<EOF #!/usr/sbin/dtrace -s #pragma D option quiet #pragma D option destructive BEGIN { printf("data\n"); freopen("/dev/stderr"); ftruncate(); freopen(""); /* re-open original stdout */ printf("more data\n"); exit(0); } EOF # chmod a+x script.d # echo foo > stdout # echo foofoo > stderr # ls -l std* -rw-r--r-- 1 root root 7 Feb 27 14:21 stderr -rw-r--r-- 1 root root 4 Feb 27 14:21 stdout # ./script.d >> stdout 2 >> stderr # ls -l std* -rw-r--r-- 1 root root 0 Feb 27 14:26 stderr -rw-r--r-- 1 root root 19 Feb 27 14:26 stdout # cat stdout foo data more data
The func action displays the function name of the kernel argument.
void jstack(int nframes, int strsize) void jstack(int nframes) void jstack(void)
jstack is an alias for ustack that uses the value of the jstackframes option for the number of stack frames and the value of the jstackstrsize option for the string space size. By default, jstacksize defaults to a non-zero value. As a result, use of jstack will result in a stack with in situ Java frame translation.
The mod action displays the module name of the kernel argument. This action is exactly the same as the sym command.
For more information, see the Data Normalization.
The print action takes a single argument. In addition to printing the input argument, it also prints the type of the input argument. The print action exploits the fact that, for kernel code, DTrace already has type information. The print action uses the type information and its own set of rules to print its argument using an appropriate format. For example, given the function:
int fop_open( struct vnode **vpp, int mode, cred_t *cr, caller_context_t *ct) {
DTrace knows that the first argument is a pointer to a struct vnode and it also knows what a struct vnode contains.
# dtrace -q -n 'fop_close:entry {print(*args[0]);exit(0)}' vnode_t { v_lock = { _opaque = [ NULL ] } v_flag = 0x36 v_count = 0x1 v_data = 0x10001f047450 v_vfsp = 0x1000102eddf0 v_stream = NULL v_type = VPROC v_rdev = 0xffffffffffffffff v_vfsmountedhere = NULL v_op = 0x10001009c040 v_pages = NULL v_filocks = NULL v_shrlocks = NULL v_nbllock = { _opaque = [ NULL ] } v_cv = { _opaque = 0x0 } v_pad = 0xcafe v_count_dnlc = 0x0 v_locality = NULL v_femhead = NULL v_path = "/proc/343325/psinfo" v_rdcnt = 0x0 v_wrcnt = 0x0 v_mmap_read = 0x0 v_mmap_write = 0x0 v_mpssdata = NULL v_fopdata = NULL v_vsd_lock = { _opaque = [ NULL ] } v_vsd = NULL v_xattrdir = NULL v_fw = 0xbaddcafebaddcafe }
printa
void printa(aggregation) void printa(string format, aggregation)
The printa action enables you to display and format aggregations. For more information about aggregations, see DTrace Aggregations. If a format is not provided, printa only traces a directive to the DTrace consumer that the specified aggregation should be processed and displayed using the default format. If a format is provided, the aggregation will be formatted as specified. For more information about the printa format string, see Output Formatting in DTrace.
printa only traces 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 the factors that affect buffer processing. These factors include the aggregation rate, the buffering policy and, if the buffering policy is switching, the rate at which buffers are switched. For more information, see DTrace Aggregations and DTrace Buffers and Buffering.
void printf(string format, ...)
Like trace, the printf action traces D expressions. However, printf enables elaborate printf style formatting. Like printa 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 dtrace according to the specified format string. For example, the first two examples of trace from trace Action could be combined in a single printf:
printf("execname is %s; priority is %d", execname, curlwpsinfo->pr_pri);
For more information about printf, see Output Formatting in DTrace. Also, see the printf(3C) man page.
setopt action enables dynamic specification of a DTrace option.
void setopt(const char *opt_name) void setopt(const char *opt_name, const char *opt_value)
For example:
setopt("quiet"); setopt("bufsize", "20m"); setopt("aggrate", "96hz");
void stack(int nframes) void stack(void)
The stack action records a kernel stack trace to the directed buffer. The kernel stack will be nframes in depth. If nframes is not provided, the number of stack frames recorded is the number specified by the stackframes option. For example:
# dtrace -n uiomove:entry'{stack()}' CPU ID FUNCTION:NAME 0 9153 uiomove:entry genunix`fop_write+0x1b namefs`nm_write+0x1d genunix`fop_write+0x1b genunix`write+0x1f7 0 9153 uiomove:entry genunix`fop_read+0x1b genunix`read+0x1d4 0 9153 uiomove:entry genunix`strread+0x394 specfs`spec_read+0x65 genunix`fop_read+0x1b genunix`read+0x1d4 ...
The stack action is a little different from other actions in that it may also be used as the key to an aggregation:
# dtrace -n kmem_alloc:entry'{@[stack()] = count()}' dtrace: description 'kmem_alloc:entry' matched 1 probe ^C rpcmod`endpnt_get+0x47c rpcmod`clnt_clts_kcallit_addr+0x26f rpcmod`clnt_clts_kcallit+0x22 nfs`rfscall+0x350 nfs`rfs2call+0x60 nfs`nfs_getattr_otw+0x9e nfs`nfsgetattr+0x26 nfs`nfs_getattr+0xb8 genunix`fop_getattr+0x18 genunix`cstat64+0x30 genunix`cstatat64+0x4a genunix`lstat64+0x1c 1 genunix`vfs_rlock_wait+0xc genunix`lookuppnvp+0x19d genunix`lookuppnat+0xe7 genunix`lookupnameat+0x87 genunix`lookupname+0x19 genunix`chdir+0x18 1 rpcmod`endpnt_get+0x6b1 rpcmod`clnt_clts_kcallit_addr+0x26f rpcmod`clnt_clts_kcallit+0x22 nfs`rfscall+0x350 nfs`rfs2call+0x60 nfs`nfs_getattr_otw+0x9e nfs`nfsgetattr+0x26 nfs`nfs_getattr+0xb8 genunix`fop_getattr+0x18 genunix`cstat64+0x30 genunix`cstatat64+0x4a genunix`lstat64+0x1c 1 ...
The sym action describes the symbol name of the kernel argument.
void trace(expression)
The most basic action is the trace action, which takes a D expression as its argument and traces the result to the directed buffer. You can force trace to use binary format for ASCII text by using the rawbytes option.
Example 17 Tracing ActionsThe 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 to record a buffer, the output format depends on the data that is collected. If dtrace decides that the data looks like an ASCII string, it prints text and the output is terminated by the first null byte. However, if dtrace decides that the data is in a binary form, it prints the output in a 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<.<........
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. tracemem 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 will dump 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 to the user. If the result is less than zero or greater than nbytes, the result is ignored and tracemem will behave as though it is called using the two argument form. Otherwise, dtrace will dump only dbytes bytes of the directed buffer.
For more information, see the Truncating Aggregations.
_usymaddr uaddr(uintptr_t address)
uaddr prints the symbol for a specified address, including hexadecimal offset. This enables the same symbol resolution that ustack provides.
# dtrace -c date -n 'pid$target::main:entry{ uaddr(0x8062578); }' dtrace: description 'pid$target::main:entry' matched 1 probe Sun Feb 3 20:58:03 PST 2008 dtrace: pid 105537 has exited CPU ID FUNCTION:NAME 0 59934 main:entry date`clock_val
In the preceding example, a call to uaddr(0x8062578) causes date`clock_val to be printed.
The following example shows how the hexadecimal offsets are printed.
demo$ sudo dtrace -n "pid\$target::main:{uaddr(uregs[R_PC])}" -c date dtrace: description 'pid$target::main:' matched 203 probes Saturday, June 9, 2012 07:06:39 AM IST CPU ID FUNCTION:NAME 0 67146 main:entry date`main 0 67147 main:0 date`main 0 67148 main:1 date`main+0x1 0 67149 main:3 date`main+0x3 0 67151 main:4 date`main+0x4 0 67152 main:5 date`main+0x5 0 67153 main:6 date`main+0x6 0 67154 main:9 date`main+0x9 0 67155 main:c date`main+0xc 0 67156 main:f date`main+0xf 0 67157 main:14 date`main+0x14 0 67158 main:16 date`main+0x16 0 67159 main:18 date`main+0x18 0 67160 main:1a date`main+0x1a 0 67161 main:1f date`main+0x1f 0 67162 main:22 date`main+0x22 0 67163 main:27 date`main+0x27 0 67164 main:2c date`main+0x2c 0 67165 main:2f date`main+0x2f 0 67166 main:34 date`main+0x34 0 67167 main:37 date`main+0x37 0 67168 main:3a date`main+0x3a 0 67169 main:3b date`main+0x3b 0 67170 main:40 date`main+0x40 0 67171 main:43 date`main+0x43 0 67172 main:46 date`main+0x46 0 67210 main:bb date`main+0xbb 0 67211 main:be date`main+0xbe 0 67212 main:c4 date`main+0xc4 0 67213 main:c6 date`main+0xc6 0 67214 main:c9 date`main+0xc9 0 67215 main:cc date`main+0xcc 0 67216 main:cf date`main+0xcf 0 67217 main:d6 date`main+0xd6 0 67221 main:dd date`main+0xdd 0 67222 main:df date`main+0xdf 0 67223 main:e5 date`main+0xe5 0 67224 main:e8 date`main+0xe8 0 67225 main:ed date`main+0xed 0 67226 main:ee date`main+0xee 0 67227 main:f0 date`main+0xf0 0 67228 main:f5 date`main+0xf5 0 67229 main:f8 date`main+0xf8 0 67230 main:fd date`main+0xfd 0 67231 main:102 date`main+0x102 0 67232 main:104 date`main+0x104 0 67233 main:10a date`main+0x10a 0 67234 main:10e date`main+0x10e 0 67258 main:156 date`main+0x156 0 67259 main:159 date`main+0x159 0 67260 main:15b date`main+0x15b 0 67261 main:160 date`main+0x160 0 67262 main:163 date`main+0x163 0 67263 main:165 date`main+0x165 0 67264 main:16c date`main+0x16c 0 67265 main:16e date`main+0x16e 0 67266 main:171 date`main+0x171 0 67267 main:176 date`main+0x176 0 67268 main:17b date`main+0x17b 0 67269 main:17e date`main+0x17e 0 67270 main:180 date`main+0x180 0 67281 main:1a9 date`main+0x1a9 0 67282 main:1ac date`main+0x1ac 0 67283 main:1b1 date`main+0x1b1 0 67284 main:1b2 date`main+0x1b2 0 67285 main:1b7 date`main+0x1b7 0 67286 main:1ba date`main+0x1ba 0 67287 main:1bc date`main+0x1bc 0 67288 main:1bf date`main+0x1bf 0 67289 main:1c0 date`main+0x1c0 0 67290 main:1c1 date`main+0x1c1 0 67291 main:1c6 date`main+0x1c6 0 67292 main:1c9 date`main+0x1c9 0 67293 main:1cc date`main+0x1cc 0 67294 main:1cd date`main+0x1cd 0 67295 main:1d2 date`main+0x1d2 0 67296 main:1d7 date`main+0x1d7 0 67297 main:1dc date`main+0x1dc 0 67298 main:1e1 date`main+0x1e1 0 67299 main:1e4 date`main+0x1e4 0 67300 main:1e9 date`main+0x1e9 0 67301 main:1ee date`main+0x1ee 0 67302 main:1f1 date`main+0x1f1 0 67303 main:1f3 date`main+0x1f3 0 67304 main:1f6 date`main+0x1f6 0 67305 main:1f7 date`main+0x1f7 0 67306 main:1f8 date`main+0x1f8 0 67307 main:1f9 date`main+0x1f9 0 67308 main:1fa date`main+0x1fa 0 2513 main:return date`main+0x1fa dtrace: pid 2972 has exited
When the noresolve option is specified, symbol resolution is not performed and the address prints as an object name and an offset within that object. Applications that contains many symbols can incur an overhead when DTrace resolves addresses to symbol names. This overhead can be reduced with the noresolve option. The object name and offset can be resolved to a symbol name by cross-referencing with the object's symbol table.
The ufunc action displays the function name of the userland argument.
The umod action displays the module name of the userland argument. This action is exactly the same as theusym command.
void ustack(int nframes, int strsize) void ustack(int nframes) void ustack(void)
The ustack action records a user stack trace to the directed buffer. The user stack will be nframes in depth. If nframes is not provided, the number of stack frames 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 will not be translated into symbols until the ustack action is processed at user-level by the DTrace consumer. If the noresolve option is set, symbol resolution is not performed, and the frames will appear only as an object name and an offset within that object. Applications that contain many symbols can incur an overhead when DTrace resolves addresses to symbol names. This overhead can be reduced with the noresolve option. The object name and offset can be resolved to a symbol name by cross-referencing with the object's symbol table. If strsize is specified and non-zero, ustack will allocate the specified amount of string space, and use it to perform address-to-symbol translation directly from the kernel. This direct user symbol translation is currently available only for Java virtual machines, version 1.5 and higher. Java address-to-symbol translation annotates user stacks that contain Java frames with the Java class and method name. If such frames cannot be translated, the frames will appear only as hexadecimal addresses.
The following example traces a stack with no string space, and therefore no Java address-to-symbol translation:
# dtrace -n syscall::write:entry'/pid == $target/{ustack(50, 0); exit(0)}' -c "java -version" dtrace: description 'syscall::write:entry' matched 1 probe java version "1.5.0-beta3" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta3-b58) Java HotSpot(TM) Client VM (build 1.5.0-beta3-b58, mixed mode) dtrace: pid 5312 has exited CPU ID FUNCTION:NAME 0 35 write:entry libc.so.1`_write+0x15 libjvm.so`__1cDhpiFwrite6FipkvI_I_+0xa8 libjvm.so`JVM_Write+0x2f d0c5c946 libjava.so`Java_java_io_FileOutputStream_writeBytes+0x2c cb007fcd cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb002a7b cb000152 libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_ pnMmethodHandle_pnRJavaCallArguments_ pnGThread__v_+0x187 libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_ pnMmethodHandle_pnRJavaCallArguments_ pnGThread__v2468_v_+0x14 libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_ pnRJavaCallArguments_pnGThread __v_+0x28 libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_ pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ ArgumentPusher_pnGThread__v_+0x180 libjvm.so`jni_CallStaticVoidMethod+0x10f java`main+0x53d
Notice that the C and C++ stack frames from the Java virtual machine are presented symbolically using C++ "mangled" symbol names, and the Java stack frames are presented only as hexadecimal addresses. The following example shows a call to ustack with a non-zero string space:
# dtrace -n syscall::write:entry'/pid == $target/{ustack(50, 500); exit(0)}' -c "java -version" dtrace: description 'syscall::write:entry' matched 1 probe java version "1.5.0-beta3" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta3-b58) Java HotSpot(TM) Client VM (build 1.5.0-beta3-b58, mixed mode) dtrace: pid 5308 has exited CPU ID FUNCTION:NAME 0 35 write:entry libc.so.1`_write+0x15 libjvm.so`__1cDhpiFwrite6FipkvI_I_+0xa8 libjvm.so`JVM_Write+0x2f d0c5c946 libjava.so`Java_java_io_FileOutputStream_writeBytes+0x2c java/io/FileOutputStream.writeBytes java/io/FileOutputStream.write java/io/BufferedOutputStream.flushBuffer java/io/BufferedOutputStream.flush java/io/PrintStream.write sun/nio/cs/StreamEncoder$CharsetSE.writeBytes sun/nio/cs/StreamEncoder$CharsetSE.implFlushBuffer sun/nio/cs/StreamEncoder.flushBuffer java/io/OutputStreamWriter.flushBuffer java/io/PrintStream.write java/io/PrintStream.print java/io/PrintStream.println sun/misc/Version.print sun/misc/Version.print StubRoutines (1) libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_ pnMmethodHandle_pnRJavaCallArguments_pnGThread __v_+0x187 libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_ pnMmethodHandle_pnRJavaCallArguments_pnGThread __v2468_v_+0x14 libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle _pnRJavaCallArguments_pnGThread__v_+0x28 libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI _jobject_nLJNICallType_pnK_jmethodID_pnSJNI _ArgumentPusher_pnGThread__v_+0x180 libjvm.so`jni_CallStaticVoidMethod+0x10f java`main+0x53d 8051b9a
The previous example output demonstrates symbolic stack frame information for Java stack frames. There are still some hexadecimal frames in this output because some functions are static and do not have entries in the application symbol table. Translation is not possible for these frames.
The ustack symbol translation for non-Java frames 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 will emit a warning message, followed by the hexadecimal stack frames, as shown in the following example:
dtrace: failed to grab process 100941: no such process c7b834d4 c7bca85d c7bca1a4 c7bd4374 c7bc2628 8047efc
Techniques for mitigating this problem are described in User Process Tracing.
Finally, because the postmortem DTrace debugger commands cannot perform the frame translation, using ustack with a ring buffer policy always results in raw ustack data.
The following D program shows an example of ustack that leaves strsize unspecified:
syscall::brk:entry /execname == $$1/ { @[ustack(40)] = count(); }
To run this example for the Oracle Solaris prstat command use the following command:
# dtrace -s brk.d prstat dtrace: script 'brk.d' matched 1 probe ^C libc.so.1`_brk_unlocked+0xa libc.so.1`sbrk+0x2d libc.so.1`_morecore+0x116 libc.so.1`_malloc_unlocked+0x193 libc.so.1`malloc+0x32 libcurses.so.1`_makenew+0x95 libcurses.so.1`newwin+0x51 libcurses.so.1`newscreen+0x593 libcurses.so.1`initscr32+0x53 prstat`curses_on+0x2a prstat`main+0x7c9 prstat`0x4057f4 1 libc.so.1`_brk_unlocked+0xa libc.so.1`sbrk+0x2d libc.so.1`_morecore+0x116 libc.so.1`_malloc_unlocked+0x193 libc.so.1`malloc+0x32 libc.so.1`calloc+0x59 libc.so.1`textdomain+0x36 prstat`main+0x3d prstat`0x4057f4 1
If the load object contains suitable DWARF then ustack can append the file name and line number of the corresponding source code to the frame description. For the following example, prstat, libcurses, and libc have been built with DWARF:
# dtrace -x uresolve=basename -s brk.d prstat dtrace: script 'brk.d' matched 1 probe ^C libc.so.1`_brk_unlocked+0xa libc.so.1`sbrk+0x2d (sbrk.c:48) libc.so.1`_morecore+0x116 (malloc.c:730) libc.so.1`_malloc_unlocked+0x193 (malloc.c:260) libc.so.1`malloc+0x32 (malloc.c:158) libcurses.so.1`_makenew+0x95 (makenew.c:53) libcurses.so.1`newwin+0x51 (newwin.c:41) libcurses.so.1`newscreen+0x593 (newscreen.c:236) libcurses.so.1`initscr32+0x53 (initscr.c:58) prstat`curses_on+0x2a (prstat.c:1314) prstat`main+0x7c9 (prstat.c:1770) prstat`0x4057f4 1 libc.so.1`_brk_unlocked+0xa libc.so.1`sbrk+0x2d (sbrk.c:48) libc.so.1`_morecore+0x116 (malloc.c:730) libc.so.1`_malloc_unlocked+0x193 (malloc.c:260) libc.so.1`malloc+0x32 (malloc.c:158) libc.so.1`calloc+0x59 (calloc.c:36) libc.so.1`textdomain+0x36 (gettext.c:88) prstat`main+0x3d (prstat.c:1564) prstat`0x4057f4 1
_usymaddr usym(uintptr_t address)
The usym action describes the symbol name of the userland argument. usym prints the symbol for a specified address. This is analogous to how uaddr works, but without the hexadecimal offsets.
uaddr: date`clock_val+0x1 usym: date`clock_val
When the noresolve option is specified, symbol resolution is not performed and the address prints as an object name and an offset within that object. Applications that contains many symbols can incur an overhead when DTrace resolves addresses to symbol names. This overhead can be reduced with the noresolve option. The object name and offset can be resolved to a symbol name by cross-referencing with the object's symbol table.