void ustack(int nframes, int strsize) void ustack(int nframes) void ustack(void)
ustack() 操作会将用户栈跟踪记录到定向缓冲区中。用户栈的深度将为 nframes。如果未提供 nframes,则记录的栈帧的数目即为 ustackframes 选项指定的数目。虽然触发探测器时,ustack() 能够确定调用帧的地址,但 DTrace 使用者在用户级处理 ustack() 操作之前,栈帧将不会转换为符号。如果指定了 strsize 且它不为零,则 ustack() 将分配指定的字符串空间量,并使用该空间直接从内核中执行地址到符号的转换。这种直接的用户符号转换当前仅在版本 1.5 和更高版本的 Java 虚拟机中可用。Java 地址到符号转换使用 Java 类和方法名注释包含 Java 帧的用户栈。如果无法转换这类帧,帧将仅显示为十六进制地址。
以下示例跟踪不包含字符串空间的栈,因此将不会进行 Java 地址到符号的转换:
# 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
|
请注意,Java 虚拟机中的 C 和 C++ 栈帧使用 C++ 的“损坏”符号名称以符号形式显示,Java 栈帧仅显示为十六进制地址。以下示例说明了对包含非零字符串空间的 ustack() 的调用:
# 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
|
以上示例的输出演示了 Java 栈帧的符号栈帧信息。该输出中仍然有一些十六进制帧,这是因为一些函数为静态函数,并在应用程序符号表中没有条目。无法对这些帧进行转换。
非 Java 帧的 ustack() 符号转换发生在记录栈数据之后。因此在执行符号转换之前,对应的用户进程可能会退出,这将使栈帧转换无法进行。如果用户进程在执行符号转换之前退出,则 dtrace 将发出一条警告消息,后跟十六进制栈帧,如下例所示:
dtrace: failed to grab process 100941: no such process
c7b834d4
c7bca85d
c7bca1a4
c7bd4374
c7bc2628
8047efc
|
第 33 章中介绍了减小此问题影响的方法。
最后,由于事后 DTrace 调试器命令无法执行帧转换,因此将 ustack() 与 ring 缓冲区策略同时使用总是会生成原始 ustack() 数据。
以下 D 程序显示了未指定 strsize 的 ustack() 示例:
syscall::brk:entry
/execname == $$1/
{
@[ustack(40)] = count();
}
要在 Netscape Web 浏览器 .netscape.bin(缺省 Solaris 安装)中运行此示例,请使用以下命令:
# dtrace -s brk.d .netscape.bin
dtrace: description 'syscall::brk:entry' matched 1 probe
^C
libc.so.1`_brk_unlocked+0xc
88143f6
88146cd
.netscape.bin`unlocked_malloc+0x3e
.netscape.bin`unlocked_calloc+0x22
.netscape.bin`calloc+0x26
.netscape.bin`_IMGCB_NewPixmap+0x149
.netscape.bin`il_size+0x2f7
.netscape.bin`il_jpeg_write+0xde
8440c19
.netscape.bin`il_first_write+0x16b
8394670
83928e5
.netscape.bin`NET_ProcessHTTP+0xa6
.netscape.bin`NET_ProcessNet+0x49a
827b323
libXt.so.4`XtAppProcessEvent+0x38f
.netscape.bin`fe_EventLoop+0x190
.netscape.bin`main+0x1875
1
libc.so.1`_brk_unlocked+0xc
libc.so.1`sbrk+0x29
88143df
88146cd
.netscape.bin`unlocked_malloc+0x3e
.netscape.bin`unlocked_calloc+0x22
.netscape.bin`calloc+0x26
.netscape.bin`_IMGCB_NewPixmap+0x149
.netscape.bin`il_size+0x2f7
.netscape.bin`il_jpeg_write+0xde
8440c19
.netscape.bin`il_first_write+0x16b
8394670
83928e5
.netscape.bin`NET_ProcessHTTP+0xa6
.netscape.bin`NET_ProcessNet+0x49a
827b323
libXt.so.4`XtAppProcessEvent+0x38f
.netscape.bin`fe_EventLoop+0x190
.netscape.bin`main+0x1875
1
...
|