Guía de seguimiento dinámico de Solaris

Acciones destructivas del núcleo

Algunas acciones son destructivas para todo el sistema. Evidentemente, estas acciones deben utilizarse con mucha precaución, ya que afectarán a todos los procesos del sistema y a cualquier otro sistema que dependa implícita o explícitamente de los servicios de red del sistema afectado.

breakpoint()

void breakpoint(void)

La acción breakpoint() induce un punto de interrupción del núcleo, provocando que el sistema se detenga y transfiera el control al depurador del núcleo, que emitirá una cadena que indicará que el sondeo de DTrace ha desencadenado la acción. Por ejemplo, si se va a realizar lo siguiente:


# dtrace -w -n clock:entry'{breakpoint()}'
dtrace: allowing destructive actions
dtrace: description 'clock:entry' matched 1 probe

En el sistema Solaris que se ejecuta en SPARC, es posible que aparezca el siguiente mensaje en la consola:


dtrace: breakpoint action at probe fbt:genunix:clock:entry (ecb 30002765700)
Type  'go' to resume
ok

En el sistema Solaris que se ejecuta en x86, es posible que aparezca el siguiente mensaje en la consola:


dtrace: breakpoint action at probe fbt:genunix:clock:entry (ecb d2b97060)
stopped at      int20+0xb:      ret
kmdb[0]:

La dirección que aparece después de la descripción del sondeo es la dirección del bloque de control de habilitación (ECB) de DTrace. Puede utilizar esta dirección para determinar detalles adicionales acerca de la habilitación del sondeo que ha provocado la acción de punto de interrupción.

Si se comete un error con la acción breakpoint(), es posible que se llame a esta acción con mayor frecuencia de la prevista. Este comportamiento podría a su vez impedir que finalice el consumidor de DTrace que está desencadenando las acciones de punto de interrupción. En esta situación, establezca la variable de entero del núcleo dtrace_destructive_disallow en 1. Esta configuración prohibirá el uso de todas las acciones destructivas en el equipo. Aplique esta configuración sólo en esta situación específica.

El método exacto para establecer dtrace_destructive_disallow dependerá del depurador del núcleo que utilice. Si utiliza OpenBoot PROM en un sistema SPARC, use w!:


ok 1 dtrace_destructive_disallow w!
ok

Confirme que la variable se haya establecido mediante w?:


ok dtrace_destructive_disallow w?
1
ok

A continuación, escriba go:


ok go

Si utiliza kmdb(1) en sistemas x86 o SPARC, use el modificador de escritura de 4 bytes (W) con el formato / dcmd:


kmdb[0]: dtrace_destructive_disallow/W 1
dtrace_destructive_disallow:    0x0             =       0x1
kmdb[0]:

A continuación, utilice :c:


kadb[0]: :c

Para volver a habilitar las acciones destructivas después de continuar con el proceso, deberá restablecer explícitamente dtrace_destructive_disallow a 0 utilizando mdb(1):


# echo "dtrace_destructive_disallow/W 0" | mdb -kw
dtrace_destructive_disallow:    0x1             =       0x0
#

panic()

void panic(void)

La acción panic() genera un aviso grave del núcleo cuando se desencadena. Esta acción debe utilizarse para forzar un volcado por fallo del sistema en el momento pertinente. Puede utilizar esta acción con el almacenamiento en memoria intermedia circular y el análisis postmortem para comprender un problema. Para obtener más información, consulte el Capítulo 11Memorias intermedias y almacenamiento en memoria intermedia y el Capítulo 37Seguimiento postmortem. Cuando se utiliza una acción de pánico, aparece un mensaje grave que indica el sondeo que está provocando la situación. Por ejemplo:


  panic[cpu0]/thread=30001830b80: dtrace: panic action at probe
  syscall::mmap:entry (ecb 300000acfc8)

  000002a10050b840 dtrace:dtrace_probe+518 (fffe, 0, 1830f88, 1830f88,
    30002fb8040, 300000acfc8)
    %l0-3: 0000000000000000 00000300030e4d80 0000030003418000 00000300018c0800
    %l4-7: 000002a10050b980 0000000000000500 0000000000000000 0000000000000502
  000002a10050ba30 genunix:dtrace_systrace_syscall32+44 (0, 2000, 5,
    80000002, 3, 1898400)
    %l0-3: 00000300030de730 0000000002200008 00000000000000e0 000000000184d928
    %l4-7: 00000300030de000 0000000000000730 0000000000000073 0000000000000010

  syncing file systems... 2 done
  dumping to /dev/dsk/c0t0d0s1, offset 214827008, content: kernel
  100% done: 11837 pages dumped, compression ratio 4.66, dump
  succeeded
  rebooting...

syslogd(1M) también emitirá un mensaje al reiniciar:


  Jun 10 16:56:31 machine1 savecore: [ID 570001 auth.error] reboot after panic:
  dtrace: panic action at probe syscall::mmap:entry (ecb 300000acfc8)

La memoria intermedia de mensajes del volcado por fallo del sistema también contiene el sondeo y el ECB responsable de la acción panic().

chill()

void chill(int nanoseconds)

La acción chill() provoca que DTrace gire durante el número especificado de nanosegundos. chill() es útil, sobre todo, para examinar problemas que puedan estar relacionados con el control del tiempo. Por ejemplo, puede utilizar esta acción para abrir las ventanas de condiciones de competencia, o sincronizar y desincronizar eventos periódicos unos con otros. Como las interrupciones están deshabilitadas cuando se encuentra el contexto de sondeo de DTrace, el uso de chill() inducirá la latencia de interrupción, programación y distribución. Por lo tanto, chill() puede provocar efectos sistémicos inesperados, y no debería utilizarse indiscriminadamente. Como las actividades del sistema utilizan la administración de interrupciones periódicas, DTrace no ejecutará la acción chill() durante más de 500 milisegundos para cada intervalo de un segundo en cualquier CPU especificada. Si se supera el intervalo máximo de chill(), DTrace informará de un error de operación no válida, como se muestra en el siguiente ejemplo:


# dtrace -w -n syscall::open:entry'{chill(500000001)}'
dtrace: allowing destructive actions
dtrace: description 'syscall::open:entry' matched 1 probe
dtrace: 57 errors
CPU     ID                    FUNCTION:NAME
dtrace: error on enabled probe ID 1 (ID 14: syscall::open:entry): \
  illegal operation in action #1

Se aplicará obligatoriamente este límite, aunque el tiempo se divida en varias llamadas a chill() o en varios consumidores de DTrace de un único sondeo. Por ejemplo, el siguiente comando generaría el mismo error:


# dtrace -w -n syscall::open:entry'{chill(250000000); chill(250000001);}'