ustack
Action
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. The ustack
action determines the frame's program counters at the point that the probe fires. These program counters are translated once the action is processed at user-level by the DTrace consumer. The translation can be modified by using the uresolve
option. For more information, see DTrace User Address Symbol Resolution.
If strsize
is specified and non-zero, ustack
allocates the specified amount of string space, and uses 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