Guía de seguimiento dinámico de Solaris

Acción ustack()

El seguimiento de la pila del subproceso de un proceso en el momento en que se activa un sondeo concreto suele resultar útil para examinar un problema con mayor detalle. La acción ustack() realiza un seguimiento de la pila del subproceso del usuario. Si, por ejemplo, un proceso que abre varios archivos falla ocasionalmente en la llamada de sistema open(2), podrá usar la acción ustack() para descubrir la ruta de código que ejecuta la acción open() que ha fallado:

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();
}

Esta secuencia de comandos también ilustra el uso de la variable de macro $1 que toma el valor del primer operando especificado en la línea de comandos de 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

La acción ustack() registra los valores del contador del programa (PC ) para la pila y dtrace(1M) resuelve estos valores PC en nombres de símbolos buscando en las tablas de símbolos del proceso. Si dtrace no puede resolver el valor PC en un símbolo, imprimirá el valor como un entero hexadecimal.

Si un proceso se cierra o se termina antes de que los datos de ustack() tengan el formato para la salida, es posible que dtrace no sea capaz de convertir los valores de PC del seguimiento de la pila en nombres de símbolos, por lo que estará obligado a mostrarlos como enteros hexadecimales. Para solucionar esta limitación, especifique un proceso de interés con la opción -c o -p para dtrace. Consulte el Capítulo 14Utilidad dtrace(1M) para obtener más información sobre estas y otras opciones. Si el ID del proceso o el comando no se conocen de antemano, se puede usar el siguiente programa escrito en D de ejemplo para solucionar esta limitación:

/*
 * 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;
}

La secuencia de comandos anterior detiene un proceso justo antes de que se cierre si la acción ustack() se ha aplicado a un subproceso de dicho proceso. Esta técnica garantiza que el comando dtrace esté disponible para resolver los valores PC en nombres simbólicos. Tenga en cuenta que el valor de stop_pids[pid] se establece en 0 después de que se haya usado para borrar la variable dinámica. Recuerde que debe ejecutar de nuevo los procesos detenidos usando el comando prun(1); de lo contrario, el sistema acumulará demasiados procesos detenidos.