【问题标题】:Linux Kernel module: printk message not where I expect to be in the buffer log [duplicate]Linux内核模块:printk消息不在我期望在缓冲区日志中的位置[重复]
【发布时间】:2018-10-07 17:09:32
【问题描述】:

此问题与实验室/家庭作业有关。我们被要求学习如何加载和删除内核模块,然后修改已提供的内核模块中的 C 代码。我们必须定义一个结构,其中包含一些要插入到链表中的元素。然后我们必须使用链表中的数据,通过 printk() 打印一些消息。

这是我的代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/types.h>


/*Defines a struct containing the elements that are to be
inserted in the linked list*/
struct birthday{
    int day;
    int month;
    int year;
    struct list_head list;
};

/*Declares a list_head object */
static LIST_HEAD(birthday_list);

/* This function is called when the module is loaded. */
int simple_init(void) { 
    /* Create and initialize instances of struct birthday*/
    struct birthday *person, *ptr;
    int count;

    printk(KERN_INFO "Loading Module\n");

    /* This loop populates the linked list with 5 nodes,
     * each with different birthday data*/
    for (count = 0; count < 5  ; count++){
        person = kmalloc(sizeof(*person), GFP_KERNEL);
        person -> day = count + 2;
        person -> month = 11 - (count + 2);
        person -> year = 1985 + ((count + 1) * 3);
        INIT_LIST_HEAD(&person -> list);
        list_add_tail(&person -> list, &birthday_list);
    }

    /*Traverse the list*/
    list_for_each_entry(ptr, &birthday_list, list) {
        printk(KERN_INFO "Birthday: Month %d Day %d Year %d\n", ptr -> month, ptr -> day, ptr -> year);
    }
    return 0;
}

/* This function is called when the module is removed. */
void simple_exit(void) {
    struct birthday *ptr, *next;

    printk(KERN_INFO "Removing Module\n");  

    list_for_each_entry_safe(ptr, next, &birthday_list, list){
        printk(KERN_INFO "Removing %d %d %d", ptr->month,     ptr->day, ptr->year);
        list_del(&ptr -> list);
        kfree(ptr);
    }
}

/* Macros for registering module entry and exit points. */
module_init( simple_init );
module_exit( simple_exit );


MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("SGG");

我可以毫无错误地编译代码,并且它似乎可以很好地加载和删除。我的问题是打印的报表。当我加载模块并使用 dmesg 检查日志缓冲区时,我可以看到所有 5 条消息(链表中的每个节点都有一条消息)。当我移除模块并检查日志缓冲区时,我只看到 4 条消息。此时不打印与链表中第 5 个节点关联的消息。如果我再次加载模块,然后检查日志缓冲区,那么第一条消息就是我删除模块时应该在日志中的消息。

当我有 5 个节点时,我才遇到过这个问题。如果我将循环更改为创建 10 个节点,所有消息都会按预期打印。 6 个节点或 4 个节点也是如此。但是每次我创建 5 个节点时都会遇到这个问题。

这是我的输出:Screenshot of my output from command line

此作业的所有编辑和操作均在 Oracle VM VirtualBox 中完成,运行在 Windows 10 中。我正在修改的 Linux 内核和内核模块作为课程材料和教科书的一部分提供。

非常感谢任何帮助!

【问题讨论】:

  • 欢迎来到 SO - 您的帖子很好,您能否将控制台输出添加为代码 sn-p 而不是屏幕截图?否则,搜索引擎将无法抓取它。

标签: c linux kernel-module printk dmesg


【解决方案1】:

这是因为您在 printk 末尾错过了 '\n'。

【讨论】:

  • 谢谢,成功了。我仍然不清楚为什么它只发生在我有 5 个节点时,当我使用 4、6 和 10 时它工作正常。这是否与我的链表中有奇数个节点有关?还是奇数个语句?
  • 这与数字无关。内核日志是面向行的。将来自不同上下文的消息分开并避免将来自不同消息的字符混合在一起存在相当复杂的逻辑。当您不使用换行符“关闭”您的消息时,该逻辑可能不会按您的预期工作。
猜你喜欢
  • 1970-01-01
  • 2016-12-13
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多