Capítulo 18. Temas avanzados

18.1. ¿Como puedo aprender más acerca del funcionamiento interno de FreeBSD?
18.2. ¿Cómo puedo contribuir a FreeBSD?
18.3. ¿Qué son snapshots y lanzamientos?
18.4. ¿Puedo seguir -CURRENT con una conexión a Internet limitada?
18.5. He escrito una extensión para el kernel ¿A quien se la envío?
18.6. ¿Como puedo aprovechar al máximo los datos que veo cuando mi kernel tiene un pánico?
18.7. ¿Por qué dlsym() ha dejado de funcionar para ejecutables ELF?
18.8. ¿Como puedo incrementar o reducir el espacio de direcciones del kernel en i386?

18.1.

¿Como puedo aprender más acerca del funcionamiento interno de FreeBSD?

Vea el Manual de arquitectura de FreeBSD.

Además, la mayor parte del conocimiento general acerca de UNIX®es directamente aplicable a FreeBSD.

18.2.

¿Cómo puedo contribuir a FreeBSD?

Vea el artículo acerca de Contribuir a FreeBSD para consejos específicos acerca de como hacer esto. ¡La ayuda es más que bienvenida!

18.3.

¿Qué son snapshots y lanzamientos?

Hay actualmente 3 ramas activas/semi activas en el repositorio Subversion de FreeBSD. (Las ramas anteriores cambian muy raramente, que es por lo cual solo hay 3 ramas de desarrollo activas):

  • stable/9/ alias 9-STABLE

  • stable/10/ alias 10-STABLE

  • head/ alias -CURRENT alias 11-CURRENT

HEAD no es realmente un tag de rama. Es una constante simbólica para el torrente de desarrollo actual, no ramificado conocido como -CURRENT.

En este momento, -CURRENT es el torrente de desarrollo 11.X; la rama 10-STABLE, stable/10/, se ramifico de -CURRENT en Enero del 2014 y la rama 9-STABLE, stable/9/, se ramifico de -CURRENT en Septiembre del 2011.

18.4.

¿Puedo seguir -CURRENT con una conexión a Internet limitada?

Si, esto puede hacerse sin descargar el árbol de código fuente entero usando la utilidad CTM.

18.5.

He escrito una extensión para el kernel ¿A quien se la envío?

Vea el artículo en Contribuyendo a FreeBSD para aprender como enviar código.

¡Y gracias por haberlo pensado!

18.6.

¿Como puedo aprovechar al máximo los datos que veo cuando mi kernel tiene un pánico?

Este es un típico pánico de kernel:

Fatal trap 12: page fault while in kernel mode
fault virtual address   = 0x40
fault code              = supervisor read, page not present
instruction pointer     = 0x8:0xf014a7e5
stack pointer           = 0x10:0xf4ed6f24
frame pointer           = 0x10:0xf4ed6f28
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 80 (mount)
interrupt mask          =
trap number             = 12
panic: page fault

Este mensaje no es suficiente. Mientras que el valor del puntero de instrucción es importante, también depende de la configuración varía en cada imagen de kernel. Si es un kernel GENERIC desde uno de los snapshots, es posible que alguien más rastree la función problemática, pero para un kernel personalizado, solo usted puede decirnos donde ocurrió el fallo.

Para proceder:

  1. Anote el valor del puntero de instrucción. Note que la parte 0x8: al inicio no es importante en este caso: es la parte 0xf0xxxxxx la que nos interesa.

  2. Cuando el sistema reinicie, haga lo siguiente:

    % nm -n kernel.que.causo.el.panico | grep f0xxxxxx

    donde f0xxxxxx es el valor del puntero de instrucción. Lo más probable es que no consiga una coincidencia exacta dado que los símbolos en la tabla de símbolos del kernel son para puntos de entrada de las funciones y la dirección del puntero de instrucción estará en algún lugar adentro de una función, no al inicio. Si no consigue una coincidencia exacta, omita el último dígito del valor del puntero de instrucción e inténtelo nuevamente:

    % nm -n kernel.que.causo.el.panico | grep f0xxxxx

    Si eso no arroja ningún resultado, elimine otro dígito. Repita hasta que haya algún tipo de salida. El resultado será una lista de posibles funciones que causaron el pánico. Este es un mecanismo poco exacto para rastrear el punto de fallo, pero es mejor que nada.

Sin embargo, la mejor manera de rastrear la causa del pánico es capturando un volcado de fallos, y luego usando kgdb(1) para generar un seguimiento de pila sobre el volcado de fallos.

En cualquier caso, el método es este:

  1. Asegúrese de que la siguiente línea esta incluida en el archivo de configuración del kernel:

    makeoptions     DEBUG=-g          # Build kernel with gdb(1) debug symbols
  2. Cambie el directorio a /usr/src:

    # cd /usr/src
  3. Compile el kernel:

    # make buildkernel KERNCONF=MYKERNEL
  4. Espere a que make(1) termine de compilar.

  5. # make installkernel KERNCONF=MYKERNEL
  6. Reinicie.

Nota:

Si KERNCONF no esta incluida, el kernel GENERIC sera compilado e instalado en su lugar.

El proceso make(1) habrá compilado dos kernels. /usr/obj/usr/src/sys/MYKERNEL/kernel y /usr/obj/usr/src/sys/MYKERNEL/kernel.debug. kernel fue instalado como /boot/kernel/kernel, mientras que kernel.debug puede ser usado como la fuente de símbolos de depuración para kgdb(1).

Para capturar un volcado de pila, edite /etc/rc.conf y ajuste dumpdev para que apunte a la partición swap o AUTO. Esto causara que los scripts de rc(8) usen el comando dumpon(8) para habilitar vocados de fallos. Este comando también puede correrse manualmente. Luego de un pánico, el volcado de fallos puede recuperarse usando savecore(8); si dumpdev esta ajustado en /etc/rc.conf, los scripts de rc(8) correran savecore(8) automáticamente y colocaran en volcado de fallos en /var/crash.

Nota:

Los volcados de fallos de FreeBSD suelen ser del mismo tamaño que la RAM física. Por consiguiente, asegúrese de que haya suficiente espacio en /var/crash para contener el volcado. Alternativamente, corra savecore(8) manualmente y haga que recupere el volcado de fallos desde otro directorio con más espacio. Es posible limitar el tamaño del volcado de fallos usando options MAXMEM=N donde Nes el tamaño del uso de memoria de kernel KBs. Por ejemplo, para 1 GB de RAM, limite el uso de memoria del kernel a 128 MB de modo que el tamaño del volcado de fallos sea de 128 MB en lugar de 1 GB.

Una vez que se haya recuperado el volcado de fallos, obtenga un seguimiento de pila de esta manera:

% kgdb /usr/obj/usr/src/sys/MYKERNEL/kernel.debug /var/crash/vmcore.0
(kgdb) backtrace

Nótese que hay varias pantallas de información. En lo posible, use script(1) para capturarlas todas. Usar la imagen unstripped del kernel con todos los símbolos de depuración debería ahora mostrar la línea exacta del codigo fuente del kernel donde ocurrio el pánico. El seguimiento de pila suele leerse desde el fondo hacía arriba para rastrear la secuencia exacta de eventos que llevaron al fallo. kgdb(1) puede también usarse para imprimir el contenido de varias variables o estructuras para examinar el estado del sistema en el momento del fallo.

Sugerencia:

Si una segunda computadora esta disponible kgdb(1) puede configurarse para realizar la depuración remota, incluyendo ajustar breakpoints y hacer single-stepping en el código del kernel.

Nota:

Si DDB esta habilitado y el kernel pasa el depurado, se pueden forzar un pánico y un volcado de fallos escribiendo panic en la consola de ddb. Esto puede detener el depurador nuevamente durante la fase de pánico. Si lo hace, escriba continue y finalizara el volcado de fallos.

18.7.

¿Por qué dlsym() ha dejado de funcionar para ejecutables ELF?

ELF toolchain por defecto no hace que los símbolos definidos a un ejecutable sean visibles al linker dinámico. Consecuentemente dlsym() busca en los descriptores obtenidos desde llamadas a dlopen(NULL, flags) y no podrá encontrar tales símbolos.

Para buscar, usando dlsym(), por símbolos presentes en el ejecutable principal de un proceso, vincule el ejecutable usando la opción --export-dynamic para el linker ELF (ld(1)).

18.8.

¿Como puedo incrementar o reducir el espacio de direcciones del kernel en i386?

Por defecto, el espacio de direcciones del kernel es de 1 GB (2 GB ppara PAE) para i386. Al correr un servidor que es intensivo sobre la red o usar ZFS, esto probablemente no sea suficiente.

Agregue la siguiente línea al archivo de configuración del kernel para incrementar el espacio disponible y recompile el kernel:

options KVA_PAGES=N

Para encontrar el valor correcto de N, divida el tamaño de espacio de direcciones deseado (en megabytes) por cuatro. (Por ejemplo, 512 para 2 GB.)

Puede descargar éste y muchos otros documentos desde ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

Si tiene dudas sobre FreeBSD consulte la documentación antes de escribir a la lista <questions@FreeBSD.org>.

Envíe sus preguntas sobre la documentación a <doc@FreeBSD.org>.