2012-04-16 11 views
18

Si tiene suerte cuando se bloquea su módulo kernel, obtendrá un ¡Vaya con un registro con mucha información, como valores en los registros, etc. Una de esas informaciones es el seguimiento de la pila (Lo mismo es cierto para los volcados del núcleo, pero originalmente había pedido esto para los módulos kernel). Tome este ejemplo:¿Cómo hacer un buen uso del seguimiento de la pila (desde el núcleo o el volcado del núcleo)?

[<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 de la función en la que se ha producido el error. Es decir, al inspeccionar este número, tal vez mirando la salida del conjunto, debería ser capaz de encontrar la línea (mejor aún, la instrucción) en la que ocurrió este error. ¿Es eso correcto?

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

Respuesta

19
skink_free_devices+0x32/0xb0 

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

Si compila su núcleo con -g habilitado, entonces se puede obtener el número de línea dentro de funciones en el control de un salto con la función addr2line o nuestra buena vieja gdb

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í simplemente ingrese la dirección que desea inspeccionar en addr2line o gdb y le indicarán el número de línea en el archivo fuente donde está presente la función ofensiva Vea el artículo this para todos los detalles de

EDIT:vmlinux es la versión sin comprimir del núcleo utilizado para la depuración y generalmente se encuentra @/lib/modules/$(uname -r)/build/vmlinux siempre que construir su núcleo a partir de fuentes. vmlinuz que se encuentra en /boot es el núcleo comprimido y puede no ser tan útil para depurar

+0

¡Yo NO sabía que usted puede gdb el linux en sí! ¡Esto es asombroso! – Shahbaz

+0

¿Dónde está 'vmlinux' though? Pensé que sería el kernel de Linux (en/boot) pero eso es 'vmlinuz ...' y addr2line dice "Formato de archivo no reconocido" No es un gran problema, ya que estoy más interesado en mis propios módulos. – Shahbaz

+0

@Shahbaz vmlinuz es simplemente la versión comprimida y/o eliminada de 'vmlinux'. BOth generalmente estará en la carpeta '/ boot'. No tengo mi linux box conmigo para verificar ahora. Google alrededor para los dos :) Aquí hay algunos principiantes. [Uno] (http://superuser.com/questions/62575/where-is-vmlinux-on-my-ubuntu-installation) y [Two] (http://superuser.com/questions/298826/how-do -i-uncompress-vmlinuz-to-vmlinux) –

1

Para usuarios de Emacs, here 's es un importante medio para saltar fácilmente alrededor dentro de la traza de la pila (addr2line utiliza internamente).

Descargo de responsabilidad: La escribí :)

+0

Ahora solo para hacer uno para ViM ... – Shahbaz

+0

Hay algo para vim (lo siento por necro): https://github.com/rzwisler/oops_trace.vim/blob/master/plugin/oops_trace.vim – stellarhopper

Cuestiones relacionadas