Você pode usar o provedor pid para rastrear qualquer instrução em qualquer função do usuário. Por demanda, o provedor pid criará um teste para cada instrução em uma função. O nome de cada teste é o deslocamento de sua instrução correspondente na função expressa como um inteiro hexadecimal. Por exemplo, para ativar um teste associado à instrução no deslocamento 0x1c na função foo do módulo bar.so no processo com PID 123, use o seguinte comando:
# dtrace -n pid123:bar.so:foo:1c |
Para ativar todos os testes na função foo, incluindo o teste de cada instrução, use o comando:
# dtrace -n pid123:bar.so:foo: |
Esse comando demonstra uma técnica extremamente poderosa para depurar e analisar os aplicativos do usuário. Erros infreqüentes podem ser difíceis de depurar por serem difíceis de reproduzir. Freqüentemente, você pode identificar um problema após a ocorrência de uma falha muito tardiamente para reconstruir o caminho do código. O exemplo seguinte demonstra como combinar o provedor pid com rastreio especulativo (consulte o Capítulo 13Rastreio especulativo) para resolver este problema rastreando cada instrução em uma função.
pid$1::$2:entry { self->spec = speculation(); speculate(self->spec); printf("%x %x %x %x %x", arg0, arg1, arg2, arg3, arg4); } pid$1::$2: /self->spec/ { speculate(self->spec); } pid$1::$2:return /self->spec && arg1 == 0/ { discard(self->spec); self->spec = 0; } pid$1::$2:return /self->spec && arg1 != 0/ { commit(self->spec); self->spec = 0; }
Executar errorpath.d resulta em uma saída semelhante ao exemplo seguinte:
# ./errorpath.d 100461 _chdir dtrace: script './errorpath.d' matched 19 probes CPU ID FUNCTION:NAME 0 25253 _chdir:entry 81e08 6d140 ffbfcb20 656c73 0 0 25253 _chdir:entry 0 25269 _chdir:0 0 25270 _chdir:4 0 25271 _chdir:8 0 25272 _chdir:c 0 25273 _chdir:10 0 25274 _chdir:14 0 25275 _chdir:18 0 25276 _chdir:1c 0 25277 _chdir:20 0 25278 _chdir:24 0 25279 _chdir:28 0 25280 _chdir:2c 0 25268 _chdir:return |