void ustack(int Anzahl_Frames, int strsize) void ustack(int Anzahl_Frames) void ustack(void)
Die Aktion ustack() zeichnet ein Benutzer-Stackprotokoll im Zielpuffer auf. Dabei ist die Tiefe des Benutzer-Stacks durch Anzahl_Frames vorgegeben. Wenn Anzahl_Frames nicht angegeben ist, werden so viele Stack-Frames aufgezeichnet, wie mit der Option ustackframes angegeben wurden. Während ustack() in der Lage ist, die Adresse der aufrufenden Frames zum Zeitpunkt der Prüfpunktauslösung zu ermitteln, werden die Stack-Frames erst in Symbole übersetzt, wenn die Aktion ustack() auf Benutzerebene vom DTrace-Verbraucher verarbeitet wurde. Wenn Größe_Zeichenkette angegeben und nicht Null ist, reserviert ustack() den angegebenen Speicherplatz für die Zeichenkette und nutzt ihn dazu, die Adresse direkt aus dem Kernel in ein Symbol zu übersetzen. Diese direkte Benutzersymbol-Übersetzung ist derzeit nur für Java Virtual Machines der Version 1.5 und höher verfügbar. Die Adress/Symbol-Übersetzung in Java kennzeichnet Benutzer-Stacks, die Java-Frames enthalten, mit der Java-Klasse und dem Methodennamen. Wenn diese Frames nicht übersetzt werden können, erscheinen diese nur als hexadezimale Adressen.
Im nächsten Beispiel wird ein Stack ohne Speicherplatz für die Zeichenkette und folglich ohne Java-Adress/Symbol-Übersetzung verfolgt:
# 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
|
Beachten Sie, dass die C- und C++-Stack-Frames aus der Java Virtual Machine symbolisch anhand von „verstümmelten“ C++-Symbolnamen und die Java-Stack-Frames nur als hexadezimale Adressen dargestellt werden. Das nächste Beispiel zeigt einen ustack()-Aufruf mit einer Zeichenkettengröße ungleich Null:
# 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
|
Die obige Beispielausgabe veranschaulicht die symbolischen Stack-Frame-Informationen zu Java-Stack-Frames. Dass weiterhin hexadezimale Frames in der Ausgabe enthalten sind, ist darauf zurückzuführen, dass einige Funktionen statisch sind und keine Einträge in der Anwendungssymboltabelle für sie vorliegen. Diese Frames können nicht übersetzt werden.
Die ustack()-Symbolübersetzung für Java-fremde Frames erfolgt nach der Aufzeichnung der Stackdaten. Folglich wird der entsprechende Benutzerprozess möglicherweise beendet, noch bevor die Symbolübersetzung durchgeführt werden kann. Dadurch wird die Stack-Frame-Übersetzung unmöglich. Wenn der Benutzerprozess vor der Symbolübersetzung beendet wird, gibt dtrace eine Warnmeldung wie im nächsten Beispiel, gefolgt von den hexadezimalen Stack-Frames aus:
dtrace: failed to grab process 100941: no such process
c7b834d4
c7bca85d
c7bca1a4
c7bd4374
c7bc2628
8047efc
|
Verfahren zur Linderung dieses Problems werden in Kapitel 33Ablaufverfolgung von Benutzerprozessen beschrieben.
Da schließlich die DTrace-Befehle zur nachträglichen Fehleranalyse (Post-Mortem-Debugging) die Frame-Übersetzung nicht durchführen können, ergibt die Verwendung von ustack() mit der ring-Pufferregel stets unverarbeitete ustack()-Daten.
Das folgende D-Programm zeigt ein Beispiel für eine ustack()-Aktion ohne Angabe von Größe_Zeichenkette:
syscall::brk:entry
/execname == $$1/
{
@[ustack(40)] = count();
}
Um dieses Beispiel auf den Webbrowser Netscape, .netscape.bin, in Solaris-Standardinstallationen anzuwenden, geben Sie folgenden Befehl ein:
# 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
...
|