2011-07-20 16 views
5

Hola soy novato en dev núcleo,pánico mientras rmmod

creado un programa simple:

#include <linux/module.h> 
#include <linux/init.h> 
#include <linux/sched.h> 
#include <linux/kthread.h> 

MODULE_LICENSE("Dual BSD/GPL"); 


int messager(void*); 
struct task_struct* kthrstr; 

static int start_module(void) 
{ 
    printk(KERN_INFO "Loading the messager\n"); 

    kthrstr = kthread_create(messager,NULL,"MESSAGER"); 
    wake_up_process(kthrstr); 
    return 0; 
} 

static void stop_module(void) 
{ 
    printk(KERN_INFO "Unloading the messager\n"); 
    kthread_stop(kthrstr); 
} 

int messager(void* varg) 
{ 
    daemonize("MESSAGER"); 
    allow_signal(SIGKILL); 

    while(1) 
    { 
     printk(KERN_INFO "Timeout: Hello"); 
     set_current_state(TASK_INTERRUPTIBLE); 
     schedule_timeout(10 * HZ); 
     if (signal_pending(current)) 
      break; 
    } 
    return 0; 
} 

module_init(start_module); 
module_exit(stop_module); 

El módulo se carga correctamente y los mensajes también aparecen en syslog como se esperaba. Pero cuando el módulo se descarga usando rmmod, entra en pánico como se muestra a continuación. Por favor me ayude a identificar como lo equivocada que está sucediendo y cómo rectificar:

[ 2207.466086] Timeout: Hello 
[ 2215.756784] Unloading the messager 
[ 2217.461846] BUG: unable to handle kernel paging request at f0ca8054 
[ 2217.462328] IP: [<f0ca8054>] 0xf0ca8054 
[ 2217.462772] *pdpt = 0000000000a76001 *pde = 000000002f8b1067 *pte = 0000000000000000 
[ 2217.463003] Oops: 0010 [#1] PREEMPT SMP 
[ 2217.463065] last sysfs file: /sys/module/ip6_tables/initstate 
[ 2217.463328] Modules linked in: fuse ip6t_LOG xt_tcpudp xt_pkttype ipt_LOG xt_limit vmsync vmblock af_packet mperf snd_pcm_oss snd_mixer_oss snd_seq_midi snd_seq_midi_event snd_seq edd ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables snd_ens1371 gameport snd_rawmidi snd_seq_device snd_ac97_codec ac97_bus snd_pcm sg snd_timer ppdev pcnet32 mptctl snd sr_mod soundcore vmci pcspkr cdrom parport_pc vmxnet shpchp snd_page_alloc parport i2c_piix4 vmw_balloon pci_hotplug floppy button ac container ext4 jbd2 crc16 linear dm_snapshot dm_mod fan processor thermal thermal_sys ata_generic mptspi mptscsih mptbase scsi_transport_spi [last unloaded: printmsg] 
[ 2217.463839] 
[ 2217.463957] Pid: 6684, comm: MESSAGER Not tainted 2.6.37.1-1.2-desktop #1 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform 
[ 2217.464156] EIP: 0060:[<f0ca8054>] EFLAGS: 00010296 CPU: 0 
[ 2217.464216] EIP is at 0xf0ca8054 
[ 2217.464249] EAX: 00000000 EBX: e8678430 ECX: 00000286 EDX: 00000000 
[ 2217.464275] ESI: 00000000 EDI: f0ca8000 EBP: 00000000 ESP: eccedfb4 
[ 2217.464302] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 
[ 2217.464414] Process MESSAGER (pid: 6684, ti=eccec000 task=e8678430 task.ti=eccec000) 
[ 2217.464450] Stack: 
[ 2217.464580] f0ca80f9 00000000 ec52ff2c c0265dc4 00000000 00000000 00000001 00000101 
[ 2217.464714] eccedfd4 eccedfd4 00000000 c0265d50 ec52ff2c c02034e6 00000000 00000000 
[ 2217.464734] 00000000 00000000 00000000 
[ 2217.464787] Call Trace: 
[ 2217.465094] Inexact backtrace: 
[ 2217.465097] 
[ 2217.476943] [<c0265dc4>] ? kthread+0x74/0x80 
[ 2217.476965] [<c0265d50>] ? kthread+0x0/0x80 
[ 2217.476985] [<c02034e6>] ? kernel_thread_helper+0x6/0x10 
[ 2217.483598] Code: Bad EIP value. 
[ 2217.483786] EIP: [<f0ca8054>] 0xf0ca8054 SS:ESP 0068:eccedfb4 
[ 2217.483849] CR2: 00000000f0ca8054 
[ 2217.484325] ---[ end trace dc9382a06b455776 ]--- 

Respuesta

3

Su módulo está fallando porque la llamada a daemonize() hace que la tarde kthread_stop() llamado a regresar sin tener que esperar.

Además, como se indica here, kthread_stop() no envía una señal al hilo, sino que hace kthread_should_stop() devuelve verdadero. en resumen, cambie su código para hacer un bucle en while (!kthread_should_stop()), y elimine las llamadas daemonize (innecesarias y peligrosas aquí) y allow_signal.

+1

¿No resultaría eso simplemente un bucle infinito en lugar de un ¡Uy! – bdonlan

+2

@bdonlan: Sí, lo haría. Parece que el problema real es la llamada 'daemonize', llamadas' daemonize' 'exit_mm', que llama a' mm_release', que señala 'vfork_done', haciendo que' kthread_stop' crea que el hilo ha terminado. esto hace que 'kthread_stop' regrese en lugar de esperar, lo que provoca el bloqueo. – Hasturkun

+2

La moraleja de la historia es, ya sea usar 'kernel_thread' y' daemonize', o usar 'kthread_create' /' kthread_run'. hacer ambas cosas al mismo tiempo te hará daño. – Hasturkun

Cuestiones relacionadas