【问题标题】:printk won't work any more after seeing some kernel taint message看到一些内核污染消息后 printk 将不再工作
【发布时间】:2013-11-09 12:38:11
【问题描述】:

全部

我正在使用 linux 内核 2.6.35 在 Fedora14 中开发一个模块。操作系统实际上是在虚拟盒子中运行的。

我观察到的是,在我对代码进行了一些更改并遇到了 taint kernel 警告之后,即使我将代码恢复到以前的版本,printk 也将不再工作。然后,如果我只是复制以前的代码以创建另一个具有不同名称的模块,它将再次工作......我不确定它是否是一个错误,但它是可重现的。

以下是运行良好的基本代码。我可以在 /var/log/messages 中看到 printk 消息

sniffer.c

#include <linux/module.h>
static int __init sniffer_init(void)
{
    printk(KERN_INFO "sniffer is initializing...");
    printk(KERN_INFO "done!\n");
    return 0;
}
static void __exit sniffer_exit(void)
{
    printk(KERN_INFO "sniffer is cleaning up...");
    printk(KERN_INFO "done!\n");
}
MODULE_AUTHOR("xyz");
MODULE_LICENSE("GPL");
module_init(sniffer_init);
module_exit(sniffer_exit);

生成文件

obj-m += sniffer.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

然后我进行了更改,这只是对多文件模块的测试

sniffer.c

#include <linux/module.h>
static int __init sniffer_init(void)
{
    printk(KERN_INFO "sniffer is initializing...");
    test_handler();
    printk(KERN_INFO "done!\n");
    return 0;
}
static void __exit sniffer_exit(void)
{
    printk(KERN_INFO "sniffer is cleaning up...");
    printk(KERN_INFO "done!\n");
}
MODULE_AUTHOR("WEICHAO HUANG");
MODULE_LICENSE("GPL");
module_init(sniffer_init);
module_exit(sniffer_exit);

生成文件

obj-m += sniffer.o
sniffer-objs := proto_handler.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

proto_handler.c

#include <linux/module.h>

void test_handler(void)
{
    printk(KERN_INFO "this is a test");
}

proto_handler.h

void test_handler(void);

然后,在我创建并运行 insmod 之后,我在 /var/log/messages 中看到了这些消息

嗅探器:模块许可证“未指定”污染内核

由于内核污染而禁用锁调试

首先,我不知道为什么会显示这些消息,因为我指定了我的许可证。

其次,在看到这些消息之后,我再也无法通过运行 insmod 或 rmmod 看到该模块的 printk 结果,即使我恢复了我的代码。但正如我所说,我可以将以前的代码复制到具有其他名称的模块中,它会再次工作。 Linux中有黑名单之类的东西吗?

谁能帮帮我?非常感谢!

【问题讨论】:

    标签: linux-kernel printk taint


    【解决方案1】:

    问题在于您的 Makefile,特别是 sniffer-objs := proto_handler.o 行。

    当你指定对象时,你必须指定所有个对象作为ko模块对象的一部分。此外,如果您有多个源文件,则源文件的名称似乎不能与最终的对象名称匹配。 IE。 sniffer.o 表示包含两个源对象的最终链接对象。因此,不要使用 sniffer.c 和 proto_handler.c,而是将名称更改为 sniffer_main.c。

    使用您当前的 makefile,sniffer.o 将只包含 proto_handler.o 的内容,其中不包含任何模块初始化或退出代码,也不包含许可证详细信息。

    这是nm sniffer.o 与您当前的makefile 的转储,请注意缺少init_module 函数和其他与模块相关的符号:

    0000000000000000 r ____versions
    0000000000000009 r __mod_vermagic5
    0000000000000000 r __module_depends
    0000000000000000 D __this_module
                     U printk
    0000000000000000 T test_handler
    

    现在,将源文件重命名为 sniffer_main.c 和 proto_handler.c,并更改以下 makefile:

    sniffer-objs := sniffer_main.o proto_handler.o
    

    最终的sniffer.o 对象内容现在包含所有必要的符号。

    nm sniffer.o:

    000000000000000  c r __mod_author13
    0000000000000000 r __mod_license14
    0000000000000000 T cleanup_module
    0000000000000000 T init_module
                     U printk
    0000000000000000 t sniffer_exit
    0000000000000000 t sniffer_init
    0000000000000000 T test_handler
    

    您还可以获得一些关于 make 输出中发生了什么的线索。使用您的原始 Makefile,sniffer.c 永远不会编译为 sniffer.o。

    【讨论】:

    • @Hanks 我无法可靠地重现您在缺少 printk 输出时看到的行为。确保/proc/sys/kernel/printk 中的值足够高以获取所有输出。
    猜你喜欢
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多