c gcc stack-trace

¿Cómo hacer un buen uso del seguimiento de la pila(desde el kernel o el volcado de núcleo)?



gcc stack-trace (2)

Para los usuarios de Emacs, here hay un modo importante para saltar fácilmente dentro del seguimiento de la pila (usa addr2line internamente).

Descargo de responsabilidad: lo escribí :)

Si tiene suerte cuando su módulo del kernel falla, obtendría un oops con un registro con mucha información, como los valores en los registros, etc. Una de esas informaciones es el seguimiento de la pila (lo mismo ocurre con los volcados de núcleos, pero originalmente había pedido esto para los módulos del kernel). Tomemos este ejemplo:

[<f97ade02>] ? skink_free_devices+0x32/0xb0 [skin_kernel] [<f97aba45>] ? cleanup_module+0x1e5/0x550 [skin_kernel] [<c017d0e7>] ? __stop_machine+0x57/0x70 [<c016dec0>] ? __try_stop_module+0x0/0x30 [<c016f069>] ? sys_delete_module+0x149/0x210 [<c0102f24>] ? sysenter_do_call+0x12/0x16

Mi conjetura es que el +<number1>/<number2> tiene algo que ver con el desplazamiento desde la función en la que se produjo el error. Es decir, al inspeccionar este número, tal vez mirando la salida del ensamblaje debería poder encontrar la línea (mejor aún, las instrucciones) en las que ocurrió este error. ¿Es eso correcto?

Mi pregunta es, ¿cuáles son estos dos números exactamente? ¿Cómo los utilizas?


skink_free_devices+0x32/0xb0

Esto significa que la instrucción ofensiva es de 0x32 bytes desde el inicio de la función skink_free_devices() que tiene 0xB0 longitud total de 0xB0 bytes.

Si compila su kernel con -g habilitado, entonces puede obtener el número de línea dentro de las funciones donde el control saltó usando la herramienta addr2line o nuestro buen gdb antiguo

Algo como esto

$ addr2line -e ./vmlinux 0xc01cf0d1 /mnt/linux-2.5.26/include/asm/bitops.h:244 or $ gdb ./vmlinux ... (gdb) l *0xc01cf0d1 0xc01cf0d1 is in read_chan (include/asm/bitops.h:244). (...) 244 return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; (...)

Así que simplemente proporcione la dirección que desea inspeccionar a addr2line o gdb y le indicarán el número de línea en el archivo fuente donde está presente la función ofensiva. Consulte this artículo para obtener todos los detalles.

EDITAR: vmlinux es la versión sin comprimir del kernel utilizada para la depuración y generalmente se encuentra en @ /lib/modules/$(uname -r)/build/vmlinux siempre que haya compilado su kernel a partir de las fuentes. vmlinuz que se encuentra en /boot es el kernel comprimido y puede que no sea tan útil en la depuración