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