void ustack(int nframes, int strsize) void ustack(int nframes) void ustack(void)
A ação ustack() registra um rastreio de pilha do usuário para o buffer direcionado. A pilha do usuário terá nframes de profundidade. Se nframes não for fornecida, o número de quadros de pilha registrado será o número especificado pela opção ustackframes. Embora ustack() possa determinar o endereço dos quadros de chamada quando o teste for acionado, os quadros de pilha não serão traduzidos em símbolos até que a ação ustack() seja processada no nível do usuário pelo consumidor do DTrace. Se strsize for especificado e diferente de zero, ustack() irá alocar a quantidade especificada de espaço de seqüência e usá-la para realizar a tradução de endereço para símbolo diretamente do kernel. Essa tradução de símbolo direta do usuário atualmente está disponível apenas para máquinas virtuais com Java, versão 1.5 e posterior. A tradução de endereço em símbolo de Java anota as pilhas de usuário que contêm quadros de Java com o nome de método e classe de Java. Se tais quadros não puderem ser traduzidos, os quadros aparecerão somente como endereços hexadecimais.
O exemplo a seguir rastreia uma pilha sem espaço de seqüência e, portanto, nenhuma tradução de endereço em símbolo 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 |
Observe que os quadros de pilhas de C e C++ da máquina virtual com Java são apresentados simbolicamente usando-se nomes de símbolos “corrompidos” de C++ e os quadros de pilhas de Java são apresentados somente como endereços hexadecimais. O exemplo a seguir mostra uma chamada para ustack() com um espaço de seqüência diferente de zero:
# 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 |
O exemplo de resultado acima demonstra informações simbólicas de quadro de pilhas de Java. Ainda existem alguns quadros hexadecimais nesse resultado porque algumas funções são estáticas e não possuem entradas na tabela de símbolos do aplicativo. A translação não é possível nesses quadros.
A translação de símbolo de ustack() para quadros que não sejam de Java ocorre depois que os dados da pilha são registrados. Por isso, o processo do usuário correspondente deve ser encerrado antes que a tradução de símbolo possa ser realizada, tornando a tradução do quadro de pilhas impossível. Se o processo do usuário for encerrado antes que a translação de símbolo seja realizada, o dtrace emitirá uma mensagem de aviso, seguida pelos quadros de pilhas hexadecimais, conforme mostrado no exemplo a seguir:
dtrace: failed to grab process 100941: no such process c7b834d4 c7bca85d c7bca1a4 c7bd4374 c7bc2628 8047efc |
As técnicas para atenuar esse problema são descritas no Capítulo 33Rastreio de processo do usuário.
Finalmente, como os comandos post mortem do depurador do DTrace não podem realizar a tradução do quadro, o uso de ustack() com uma política de buffer ring sempre resulta em dados ustack() não processados.
O programa em D a seguir mostra um exemplo de ustack() que deixa strsize sem especificação:
syscall::brk:entry /execname == $$1/ { @[ustack(40)] = count(); }
Para executar este exemplo para o navegador da Web Netscape, .netscape.bin em instalações padrão do Solaris, use o seguinte 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 ... |