Guia de rastreamento dinâmico Solaris

Ação ustack()

Rastrear uma pilha do segmento do processo na hora em que um teste específico é ativado é freqüentemente útil para examinar um problema em maiores detalhes. A ação ustack() rastreia a pilha do segmento do usuário. Se, por exemplo, um processo que abre muitos arquivos falhar ocasionalmente na chamada do sistema open(2), use a ação ustack() para descobrir o caminho do código que executa a função open() falha:

syscall::open:entry
/pid == $1/
{
	self->path = copyinstr(arg0);
}

syscall::open:return
/self->path != NULL && arg1 == -1/
{
	printf("open for '%s' failed", self->path);
	ustack();
}

Este script também ilustra o uso da variável de macro $1 que usa o valor do primeiro operando especificado na linha de comando do dtrace(1M):


# dtrace -s ./badopen.d 31337
dtrace: script './badopen.d' matched 2 probes
CPU     ID                    FUNCTION:NAME
  0     40                      open:return open for '/usr/lib/foo' failed
              libc.so.1`__open+0x4
              libc.so.1`open+0x6c
              420b0
              tcsh`dosource+0xe0
              tcsh`execute+0x978
              tcsh`execute+0xba0
              tcsh`process+0x50c
              tcsh`main+0x1d54
              tcsh`_start+0xdc

A ação ustack() registra os valores do contador do programa ( PC) da pilha e o dtrace(1M) resolve esses valores de PC para nomes de símbolo, procurando nas tabelas de símbolos do processo. Se o dtrace não puder resolver o valor de PC para um símbolo, ele imprimirá o valor como um inteiro hexadecimal.

Se um processo sair ou for interrompido antes de os dados de ustack() serem formatados para saída, o dtrace talvez não consiga converter os valores de PC no rastreamento da pilha para nomes de símbolo, e será forçado a exibi-los como inteiros hexadecimais. Para resolver esta limitação, especifique um processo de interesse com a opção -c ou -p para dtrace. Consulte o Capítulo 14Utilitário dtrace(1M) para obter detalhes sobre estas e outras opções. Se o ID do processo ou o comando não for conhecido com antecedência, o exemplo seguinte de programa em D poderá ser usado para resolver a limitação:

/*
 * This example uses the open(2) system call probe, but this technique
 * is applicable to any script using the ustack() action where the stack
 * being traced is in a process that may exit soon.
 */
 syscall::open:entry
{
	ustack();
	stop_pids[pid] = 1;
}

syscall::rexit:entry
/stop_pids[pid] != 0/
{
	printf("stopping pid %d", pid);
	stop();
	stop_pids[pid] = 0;
}

O script acima irá parar um processo antes que ele saia, se a ação ustack() tiver sido aplicada a um segmento nesse processo. Esta técnica garante que o comando dtrace será capaz de resolver os valores de PC para nomes simbólicos. Observe que o valor de stop_pids[pid] é definido como 0 depois que ele tiver sido usado para limpar a variável dinâmica. Lembre-se de definir os processos interrompidos que estão sendo executados novamente usando o comando prun(1) ou o seu sistema acumulará muitos processos interrompidos.