Manuel de suivi dynamique Solaris

ustack()

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
    ...