Guía de seguimiento dinámico de Solaris

ustack()

void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)

La acción ustack() registra un seguimiento de la pila del usuario en la memoria intermedia dirigida. La pila del usuario tendrá una profundidad de nframes. Si no se especifica el valor de nframes, el número de marcos de pila registrados será el número especificado por la opción ustackframes. Aunque ustack() puede determinar la dirección de los marcos de llamada cuando se activa el sondeo, los marcos de pila no se convertirán en símbolos hasta que el consumidor de DTrace no procese la acción ustack() a nivel de usuario. Si se especifican strsize y un valor diferente a cero, ustack() asignará la cantidad especificada de espacio de cadena y la utilizará para convertir las direcciones en símbolos directamente desde el núcleo. Esta traducción directa de símbolos de usuario está sólo disponible actualmente para la versión 1.5 y superior de la Máquina virtual de Java. La función de traducción de direcciones en símbolos de Java anota las pilas de usuarios que contienen marcos de Java con la clase de Java y el nombre del método. Si no es posible traducir esos marcos, aparecerán sólo como direcciones hexadecimales.

El siguiente ejemplo realiza un seguimiento de una pila sin espacio de cadena y, por lo tanto, sin traducción de direcciones en símbolos de 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

Tenga en cuenta que los marcos de pila de C y C++ de la Máquina virtual de Java se presentan de forma simbólica mediante nombres de símbolos "corruptos" de C++ y los marcos de pila de Java se presentan únicamente como direcciones hexadecimales. En el siguiente ejemplo, se muestra una llamada a ustack() con un espacio de cadena diferente a cero.


# 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

La salida del ejemplo anterior muestra la información de marcos de pila simbólicos para los marcos de pila de Java. Aún hay varios marcos hexadecimales en esta salida, ya que algunas funciones son estáticas y no tienen entradas en la tabla de símbolos de la aplicación. Por lo tanto, no se puede realizar la traducción para estos marcos.

La traducción en símbolos de ustack() para los marcos que no son de Java se produce después de registrar los datos de la pila. Por lo tanto, es posible que se cierre el proceso de usuario antes de que se realice la traducción en símbolos, por lo que la traducción de los marcos de pila no se podría realizar. Si el proceso de usuario se cierra antes de que se realice la traducción en símbolos, dtrace emitirá un mensaje de advertencia, seguido de los marcos de pila hexadecimales, como se muestra en el siguiente ejemplo:


  dtrace: failed to grab process 100941: no such process
                c7b834d4
                c7bca85d
                c7bca1a4
                c7bd4374
                c7bc2628
                8047efc

Las técnicas para solucionar este problema se describen en el Capítulo 33Seguimiento de procesos de usuario.

Por último, dado que los comandos del depurador de DTrace postmortem no pueden realizar la traducción de los marcos, el uso de ustack() con una directiva de memoria intermedia ring siempre generará datos de ustack() sin formato.

El siguiente programa D muestra un ejemplo de ustack() en el que se deja sin especificar strsize:

syscall::brk:entry
/execname == $$1/
{
	@[ustack(40)] = count();
}

Para ejecutar este ejemplo en el explorador Web de Netscape, .netscape.bin en las instalaciones predeterminadas de Solaris, utilice el siguiente comando:


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