2011-06-02 14 views
14

Escribo mi primer módulo de núcleo Linux, que en realidad es un controlador RAM disk más algunas características adicionales. Cuando traté de insmod el módulo, "Error de segmentación" sucedió.Rastreo de llamadas al cargar un módulo en Linux

Y aquí está el registro del kernel correspondiente, en realidad dos pedazos de mensajes del kernel oops. Después de leer una gran cantidad de tutoriales relacionados, todavía tengo algunas preguntas con respecto a este registro:

1) En la lista de llamadas, hay funciones precedidas con y sin signos de interrogación, ¿cuál es el significado especial del signo de interrogación "? " para esa función?

2) Mi comprensión del seguimiento de llamadas es: cada función, excepto la inferior, debe ser llamada por la siguiente. Pero para esto:

[ 397.855035] [<c05a603b>] ? exact_lock+0x0/0x16 
    [ 397.855035] [<f787c252>] ? diag_init+0x252/0x4bd [b2bntb_diag] 
    [ 397.855035] [<c0451e35>] ? __blocking_notifier_call_chain+0x42/0x4d 
    [ 397.855035] [<f787c000>] ? diag_init+0x0/0x4bd [b2bntb_diag] 

diag_init la función init del módulo escrito por mí. No llama a ninguna función llamada exact_lock o __blocking_notifier_call_chain, ¿cómo es que estas dos funciones aparecen así en el rastreo de llamadas aquí?

3) ¿Cuál es el error y cómo resolverlo?

BTW, el kernel de Linux que estoy ejecutando tiene la versión 2.6.35.6.

[ 397.850955] ------------[ cut here ]------------ 
[ 397.851544] WARNING: at lib/kobject.c:168 kobject_add_internal+0x3a/0x1e2() 
[ 397.851601] Hardware name: VirtualBox 
[ 397.851639] kobject: (f4580258): attempted to be registered with empty name! 
[ 397.851678] Modules linked in: b2bntb_diag(+) fuse vboxvideo drm sunrpc ip6t_REJECT nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 vboxsf uinput snd_intel8x0 snd_ac97_codec vboxguest ac97_bus snd_seq snd_seq_device ppdev snd_pcm parport_pc parport microcode snd_timer joydev snd e1000 i2c_piix4 soundcore i2c_core snd_page_alloc [last unloaded: mperf] 
[ 397.852707] Pid: 1958, comm: insmod Tainted: G  W 2.6.35.6-45.fc14.i686 #1 
[ 397.852749] Call Trace: 
[ 397.852828] [<c043938d>] warn_slowpath_common+0x6a/0x7f 
[ 397.852970] [<c05b054d>] ? kobject_add_internal+0x3a/0x1e2 
[ 397.853130] [<c0439415>] warn_slowpath_fmt+0x2b/0x2f 
[ 397.853182] [<c05b054d>] kobject_add_internal+0x3a/0x1e2 
[ 397.853235] [<c05b098b>] kobject_add+0x5b/0x66 
[ 397.853292] [<c064e8e3>] device_add+0xda/0x4b6 
[ 397.853346] [<c05b7bc7>] ? kvasprintf+0x38/0x43 
[ 397.853394] [<c05b08e0>] ? kobject_set_name_vargs+0x46/0x4c 
[ 397.853467] [<c051b9bc>] register_disk+0x31/0x109 
[ 397.853528] [<c05a6234>] ? blk_register_region+0x20/0x25 
[ 397.853579] [<c05a6b08>] add_disk+0x9f/0xf0 
[ 397.853627] [<c05a5bff>] ? exact_match+0x0/0xd 
[ 397.853678] [<c05a603b>] ? exact_lock+0x0/0x16 
[ 397.853731] [<f787c252>] diag_init+0x252/0x4bd [b2bntb_diag] 
[ 397.853785] [<c0451e35>] ? __blocking_notifier_call_chain+0x42/0x4d 
[ 397.853836] [<f787c000>] ? diag_init+0x0/0x4bd [b2bntb_diag] 
[ 397.853889] [<c0401246>] do_one_initcall+0x4f/0x139 
[ 397.853967] [<c0451e51>] ? blocking_notifier_call_chain+0x11/0x13 
[ 397.854086] [<c04621a4>] sys_init_module+0x7f/0x19b 
[ 397.854142] [<c07a7374>] syscall_call+0x7/0xb 
[ 397.854177] ---[ end trace 6dc509801197bdc3 ]--- 
[ 397.855035] ------------[ cut here ]------------ 
[ 397.855035] kernel BUG at fs/sysfs/group.c:65! 
[ 397.855035] invalid opcode: 0000 [#1] SMP 
[ 397.855035] last sysfs file: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0C0A:00/power_supply/BAT0/energy_full 
[ 397.855035] Modules linked in: b2bntb_diag(+) fuse vboxvideo drm sunrpc ip6t_REJECT nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 vboxsf uinput snd_intel8x0 snd_ac97_codec vboxguest ac97_bus snd_seq snd_seq_device ppdev snd_pcm parport_pc parport microcode snd_timer joydev snd e1000 i2c_piix4 soundcore i2c_core snd_page_alloc [last unloaded: mperf] 
[ 397.855035] 
[ 397.855035] Pid: 1958, comm: insmod Tainted: G  W 2.6.35.6-45.fc14.i686 #1 /VirtualBox 
[ 397.855035] EIP: 0060:[<c0520d15>] EFLAGS: 00010246 CPU: 0 
[ 397.855035] EIP is at internal_create_group+0x23/0x103 
[ 397.855035] EAX: f4580258 EBX: f4580258 ECX: c09d4344 EDX: 00000000 
[ 397.855035] ESI: f60521f0 EDI: c09d4344 EBP: f45b7ef0 ESP: f45b7ed0 
[ 397.855035] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 
[ 397.855035] Process insmod (pid: 1958, ti=f45b6000 task=f3a68ca0 task.ti=f45b6000) 
[ 397.855035] Stack: 
[ 397.855035] 00000000 f45b7ee4 c05b08e0 8eecb04c f4580200 f4580200 f60521f0 f4580200 
[ 397.855035] <0> f45b7ef8 c0520e1c f45b7f00 c0498de9 f45b7f18 c05a261a f4580250 f4580200 
[ 397.855035] <0> 00000001 00000000 f45b7f38 c05a6b0f c05a5bff c05a603b f4580200 0fc00000 
[ 397.855035] Call Trace: 
[ 397.855035] [<c05b08e0>] ? kobject_set_name_vargs+0x46/0x4c 
[ 397.855035] [<c0520e1c>] ? sysfs_create_group+0x11/0x15 
[ 397.855035] [<c0498de9>] ? blk_trace_init_sysfs+0x10/0x12 
[ 397.855035] [<c05a261a>] ? blk_register_queue+0x3b/0xac 
[ 397.855035] [<c05a6b0f>] ? add_disk+0xa6/0xf0 
[ 397.855035] [<c05a5bff>] ? exact_match+0x0/0xd 
[ 397.855035] [<c05a603b>] ? exact_lock+0x0/0x16 
[ 397.855035] [<f787c252>] ? diag_init+0x252/0x4bd [b2bntb_diag] 
[ 397.855035] [<c0451e35>] ? __blocking_notifier_call_chain+0x42/0x4d 
[ 397.855035] [<f787c000>] ? diag_init+0x0/0x4bd [b2bntb_diag] 
[ 397.855035] [<c0401246>] ? do_one_initcall+0x4f/0x139 
[ 397.855035] [<c0451e51>] ? blocking_notifier_call_chain+0x11/0x13 
[ 397.855035] [<c04621a4>] ? sys_init_module+0x7f/0x19b 
[ 397.855035] [<c07a7374>] ? syscall_call+0x7/0xb 
[ 397.855035] Code: 8d 65 f4 5b 5e 5f 5d c3 55 89 e5 57 56 53 83 ec 14 0f 1f 44 00 00 85 c0 89 c3 89 55 e0 89 cf 74 0a 85 d2 75 08 83 78 18 00 75 11 <0f> 0b 83 78 18 00 be ea ff ff ff 0f 84 c5 00 00 00 8b 17 85 d2 
[ 397.855035] EIP: [<c0520d15>] internal_create_group+0x23/0x103 SS:ESP 0068:f45b7ed0 
[ 397.865682] ---[ end trace 6dc509801197bdc4 ]--- 
[[email protected] ntb]# 

Respuesta

16

El primer mensaje de oops es en realidad una advertencia del kernel. La parte importante de la advertencia es aquí: "¡intentó registrarse con el nombre vacío!". Significa que no se proporcionó un campo de cadena de nombre descriptivo en un kobject. Específicamente, dado que en el rastro de llamada de la advertencia vemos register_disk, supongo que olvidaste iniciar apropiadamente el campo de nombre de una estructura que pasaste durante el registro. Esta es la parte de advertencia.

El siguiente mensaje es un bloqueo real: algunos códigos en el sistema de archivos sysfs que intentaron crear el nombre de un grupo a partir del nombre que se suponía que debían dar en su proceso de registro afectan a una afirmación de tiempo de ejecución del núcleo. al campo de nombre faltante.

Así que esta es la razón por la que está fallando. Acerca de sus preguntas: algunas de las funciones que ve en el rastreo se llaman en realidad desde funciones en línea (y/o macros) que se usan en su código. Entonces su código los está llamando, aunque no por su nombre.

Acerca del signo de interrogación, el mecanismo de seguimiento de la pila del kernel informa si la búsqueda de dirección a nombre de símbolo es "confiable" o no. No estoy 100% seguro de lo que eso significa, pero si no aparece, recibirá el signo de interrogación en el nombre del símbolo.

Cuestiones relacionadas