【问题标题】:Kernel unable to handle NULL pointer dereference - using kmem_cache_alloc with struct内核无法处理 NULL 指针取消引用 - 使用带有结构的 kmem_cache_alloc
【发布时间】:2012-11-09 17:02:14
【问题描述】:

我正在尝试编写一个简单的字符驱动程序,以尝试了解有关 Linux 驱动程序的更多信息。

驱动程序的想法是有一个链表,在每个节点中将包含一个字符和一个指向下一个节点的指针。我打算使用 kmem_cache 来构建这个链表,因为我认为根据需要一次为单个节点分配一个对象会很简单。

这是我遇到问题的相关代码。这并不漂亮,因为我只是想让这件事发挥作用。

struct kmem_cache *memCache;

typedef struct {
    char data;
    struct node* next;
} node;

node *head = NULL;

static ssize_t hello_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
    int i;
    accesscount++;

    for(i = 0; i < count; i++)
    {
        node *finder;
        node *temp;

        finder = head;

        if(finder == NULL)
        {
            finder = kmem_cache_alloc(memCache, GFP_KERNEL);
            //memset(finder, 0, sizeof(node)); 

            if(!finder)
                return -ENOMEM;

            finder->next = NULL;

            //!!!NULL DEREFERENCE HERE!!!
            copy_from_user(finder->data, buf+i, 1);

            head = finder;
        }
        else
        {
            while(finder->next != NULL)
                finder = finder->next;

            temp = kmem_cache_alloc(memCache, GFP_KERNEL);
            //memset(temp, 0, sizeof(node)); 

            if(!temp)
                return -ENOMEM;

            temp->next = NULL;

            copy_from_user(temp->data, buf+i, 1);

            finder->next = temp;
        }

        charsStored++;  
    }

    return count;
}

static int __init hello_init(void)
{
    memCache = kmem_cache_create("hello1", sizeof(node), 0, 0, NULL);
}

正如您从我的评论中看到的那样,当我调用 copy_from_user() 并在节点中传递 char 变量时,我会得到一个 null 取消引用。我想既然我为节点分配了内存,它不应该再为空了。我也尝试将 char 设置为 char* 并得到不同的结果,但它仍然无法正常工作。

我知道我的问题在于我如何分配内存或构建指针的方式,但我真的被困在这里。我希望有人知道这里出了什么问题。

【问题讨论】:

  • 你确定空解引用是什么?我的猜测是 buf 是问题而不是 finder/head...在那里获取一些调试输出... :)
  • 我不确定它是否是 buf,因为如果我将 struct 中的 char 数据更改为 char* 数据,我将不再获得 null 取消引用,但我得到另一个错误,我现在不记得了。不幸的是,我现在无法再次测试它,因为我正在工作,并且我正在家里的 BeagleBoard 上运行此代码。

标签: c linux-device-driver


【解决方案1】:

将 finder->data 的地址而不是它的值传递给 copy_from_user,我想你会准备好的。

【讨论】:

  • 我回家后一定会尝试的。不知道为什么我没有想到...啊睡眠剥夺...
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 2011-02-04
  • 2015-12-31
相关资源
最近更新 更多