您好,我是kernel dev的新手,
创建了一个简单的程序:
#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);
模块正确加载,消息也按预期显示在syslog中。但是当使用rmmod卸载模块时,它会发生恐慌,如下所示。请帮助我确定发生了什么错误以及如何纠正:
[ 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 ]---
答案 0 :(得分:3)
您的模块崩溃了,因为对daemonize()
的调用导致后来的kthread_stop()
调用无需等待即可返回。
此外,如上所述here,kthread_stop()
不会向线程发送信号,而是使kthread_should_stop()
返回true。简而言之,将代码更改为while (!kthread_should_stop())
上的循环,并删除daemonize
(此处不需要和危险)和allow_signal
来电。