void ustack(int nframes, int strsize) void ustack(int nframes) void ustack(void)
L'action ustack() enregistre une trace de pile utilisateur dans le tampon spécifié. La pile utilisateur aura une profondeur de nframes. Si nframes n'est pas fourni, le nombre de cadres de pile enregistrés correspond au nombre spécifié par l'option ustackframes. Tant que ustack() est capable de déterminer l'adresse de cadres d'appel lorsque la sonde se déclenche, les cadres de pile ne seront convertis en symbole qu'au moment où le consommateur DTrace traite l'action ustack() au niveau utilisateur. Si strsize est spécifié et que sa valeur est différente de zéro, ustack() alloue l'espace de chaîne spécifié pour effectuer une conversion d'adresse en symbole directement depuis le noyau. Cette conversion directe en symbole utilisateur est actuellement disponible uniquement sur les machines virtuelles Java 1.5 ou une version supérieure. La conversion Java d'adresse en symbole annote les piles utilisateur contenant des cadres Java avec un nom de méthode et une classe Java. Si ces cadres ne peuvent pas être convertis, ils apparaîtront uniquement en tant qu'adresses hexadécimales.
L'exemple suivant effectue le suivi d'une pile sans espace de chaîne, et donc sans conversion Java d'adresse en symbole.
# 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 |
Vous remarquerez que les cadres de pile C et C++ de la machine virtuelle Java sont présentés symboliquement, en utilisant des noms symboliques “mutilés” C++ tandis que les cadres de pile Java sont présentés uniquement sous forme d'adresses hexadécimales. L'exemple suivant illustre un appel à ustack() avec un espace de chaîne dont la valeur est différente de zéro :
# 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 |
Le résultat de l'exemple ci-dessus affiche des informations symboliques sur les cadres de pile Java. Des cadres hexadécimaux restent affichés dans cette sortie car certaines fonctions sont statiques et n'ont pas d'entrée dans le tableau des symboles d'application. La conversion est impossible pour ces cadres.
La conversion du symbole ustack() pour les cadres autres que Java se produit après l'enregistrement des données de pile. Par conséquent, le processus utilisateur correspondant risque de se terminer avant la réalisation de la conversion du symbole, rendant la conversion des cadres de pile impossible. Si le processus utilisateur se termine avant la réalisation de la conversion du symbole, dtrace émet un message d'avertissement, suivi des cadres de pile hexadécimaux, comme illustré dans l'exemple suivant :
dtrace: failed to grab process 100941: no such process c7b834d4 c7bca85d c7bca1a4 c7bd4374 c7bc2628 8047efc |
Vous trouverez davantage d'informations sur les techniques pour restreindre ce problème au Chapitre33Suivi des processus utilisateur.
Enfin, étant donné que les commandes du débogueur DTrace post-mortem ne peuvent pas exécuter la conversion des cadres, l'utilisation de ustack() avec une stratégie de tampon ring donnera des données ustack() brutes.
Le programme D suivant montre un exemple de ustack() laissant strsize non spécifié :
syscall::brk:entry /execname == $$1/ { @[ustack(40)] = count(); }
Pour exécuter cet exemple destiné au navigateur Web Netscape .netscape.bin dans les installations Solaris par défaut, utilisez la commande suivante :
# 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 ... |