9.4. Depuración En-línea del Kernel Usando DDB

Si bien el kgdb provee un muy alto nivel de interfaz de usuario como depurador post-mortem, hay cosas que no puede hacer. Siendo las más importantes poder marcar puntos de interrupción y ejecutar código del kernel paso a paso.

Si usted necesita hacer una depuración a bajo nivel de su kernel hay disponible un debugger en-línea llamado DDB. Permite poner puntos de interrupción, ejecutar paso a paso las funciones del kernel, examinar y cambiar variables, etc. Sin embargo, no puede acceder al código fuente del kernel y sólo tiene acceso a los símbolos globales y estáticos, no a toda la información de depuración como el kgdb.

Para configurar su kernel para que incluya el DDB, agregue la opción

options DDB
a su archivo de configuración, y recompile (vea Configuración del Kernel para más detalles sobre como configurar el kernel de FreeBSD.)

Nota: Notese que si usted tiene una versión vieja del boot block, sus símbolos de debugger podrían no ser cargados. Actualize su boot block; los mas recientes cargan los símbolos del DDB automágicamente.

Una vez que su kernel con DDB esta corriendo, hay varias maneras de entrar al DDB. La primera y más temprana es tipear la opción -d directamente en el prompt de inicio. El kernel se iniciará en modo de depuración e ingresará al DDB antes de cualquier detección de dispositivos. De aquí en adelante usted podrá depurar hasta las funciones probe/attach de los dispositivos.

El segundo escenario es una combinación de teclas, generalmente Ctrl-Alt-Esc. En el caso de las syscons, esto puede modificarse, algunos mapas de teclado distribuidos lo hacen, por lo que hay que prestar atención. Hay disponible una opción para consolas en puertos serie que permite el uso de la señal BREAK en la línea para entrar al DDB (options BREAK_TO_DEBUGGER en el archivo de configuración del kernel). Esto no es el default ya que hay un montón de adaptadores serie dando vueltas que generan condiciones BREAK sin necesidad, por ejemplo cuando se desenchufa el cable.

La tercera forma es que un panic salte al DDB si el kernel está configurado para usarlo. Por este motivo, no es recomendable configurar un kernel con DDB para una máquina funcionando sin atención.

Los comandos del DDB se asemejan remotamente a algunos de los del gdb. Lo primero que usted probablemente necesite hacer es poner un punto de interrupción:

b nombre-de-función
b dirección

Por default los números se toman en hexadecimal, pero para distinguirlos de los nombres de símbolo los números hexadecimales que empiezan con las letras a-f se deben preceder con 0x (para los demás números esto es opcional). Tambien se admiten expresiones sencillas, por ejemplo: nombre-de-función + 0x103.

Para que el kernel interrumpido continue ejecutandose, solo tipee:

c

Para ver un listado de la pila, use:

trace

Nota: Notese que cuando se entra al DDB con una combinación de teclas el kernel está atendiendo una interrupción, por lo que el listado de la pila podría no serle de mucha utilidad.

Si quiere quitar un punto de interrupción, use

del
del expresión-dirección-de-memoria

La primera forma se aceptará inmediatamente despues de llegar a un punto de interrupción, y borra el punto actual. La segunda puede quitar cualquier punto de interrupción, pero se debe especificar la dirección exacta; esta se puede obtener de:

show b

Para ejecutar el kernel paso a paso, intente:

s

Esto entrará dentro de las funciones, pero puede hacer que DDB las siga hasta llegar a la instrucción de retorno correspondiente usando:

n

Nota: Esto es distinto de la instrucción next del gdb; es más parecido a la instrucción finish.

Para examinar los datos en la memoria use (por ejemplo):

x/wx 0xf0133fe0,40
x/hd db_symtab_space
x/bc termbuf,10
x/s stringbuf
para acceder a palabras/medias palabras/bytes, y para mostrar en hexadecimal/decimal/caracteres/strings. El número luego de la coma es la cantidad de objetos. Para mostrar los siguientes 0x10 items, simplemente use:

x ,10

Del mismo modo, use

x/ia foofunc,10
para desensamblar las primeras 0x10 instrucciones de foofunc, y mostrarlas junto con su desplazamiento desde el comienzo de foofunc.

Para modificar memoria, use el comando write:

w/b termbuf 0xa 0xb 0
w/w 0xf0010030 0 0

El modificador (b/h/w) especifica el tamaño de los datos a ser escritos, la primera expresión a continuación es la dirección donde escribir y el resto es interpretado como datos para escribir en las direcciones de memoria sucesivas.

Si quiere conocer el valor actual de los registros del procesador, use:

show reg

O, puede mostrar un solo registro usando:

p $eax
y modificarlo haciendo:

set $eax new-value

Si usted quisiera llamar alguna función del kernel desde el DDB, solo debe decir:

call func(arg1, arg2, ...)

El valor devuelto será impreso en la pantalla.

Para un resumen de los procesos corriendo al estilo ps(1) use:

ps

Usted ya ha examinado la causa de que su kernel falle, y quiere reiniciar su equipo. Recuerde que, dependiendo de lo severo de las fallas que ocurrieron, algunas partes del kernel podrían no funcionar como se espera. Siga una de las siguientes acciones para apagar y reiniciar su equipo:

call diediedie()

Esto causará que su kernel haga un crash dump y reinicie, asi luego podrá analizar el dump a un nivel más alto con el kgdb. Este comando suele tener que acompañarse por otra instrucción continue. Para hacer esto hay un alias: panic.

call boot(0)

La cual podría ser una buena manera de apagar ordenadamente el sistema, hacer un sync() de todos los discos, y finalmente reiniciar. En tanto las interfaces de disco y de filesystem del kernel no esten dañadas, esta podría ser una buena manera de hacer un apagado bastante prolijo.

call cpu_reset()

Es la ultima salida de los desastres y es practicamente lo mismo que presionar el Gran Boton Rojo.

Si usted necesita un breve sumario de los comandos, tipee:

help

De todos modos, es altamente recomendable tener una copia impresa de la página ddb(4) del manual a mano antes de la sesión de depuración. Recuerde que es bastante difícil leer el manual en línea mientras se está ejecutando el kernel paso a paso.

Éste y otros documentos pueden obtenerse en ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

Para preguntas acerca de FreeBSD, leer la documentación antes de contactar con la lista <questions@FreeBSD.org>.
Para preguntas acerca de esta documentación, e-mail a <doc@FreeBSD.org>.