C 指针最近不为空时出现空指针取消引用错误

C 指针最近不为空时出现空指针取消引用错误,c,linux-kernel,C,Linux Kernel,我正在编写Linux内核模块,遇到一些问题: 我的模块在检查了这些指针值后就进入了关键点 static struct area_control { struct list_head head; unsigned long addr; unsigned long jiffies; struct area_part *part; } *const_areas = NULL, *var_areas = NULL; static struct area_control

我正在编写Linux内核模块,遇到一些问题: 我的模块在检查了这些指针值后就进入了关键点

static struct area_control {
    struct list_head head;
    unsigned long addr;
    unsigned long jiffies;
    struct area_part *part;
} *const_areas = NULL, *var_areas = NULL;

static struct area_control *Find_Area(unsigned long addr, struct area_control *first_area)
{
    if (first_area)
    {
        struct area_control *cur_area = first_area;
        while ( 1 ) 
        {
            if (!cur_area) return NULL;
            if (cur_area->addr == addr)
            {
                cur_area->jiffies = jiffies;
                return cur_area;
            }
            cur_area = list_entry(cur_area->head.next, struct area_control, head);
            if (cur_area == first_area) return NULL;
        }
    }
    return NULL;
}
在某一点上
cur\u area->head.next
由于cur_区域为空,模块下降!-这是我从调用跟踪和反汇编程序得到的事实。Linux 2.6.34 x86_64多处理器体系结构模块

        cur_area = list_entry(cur_area->head.next, struct area_control, head);

您需要检查
cur\u区域->头部。下一步
也是
NULL

使用宏定义:

#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member)))
代码将扩展为:

        cur_area = ((struct area_control *)((char *)(cur_area->head.next) - (unsigned long(&((struct area_control *)0)->head)))

如您所见,如果
cur\u area->head,此代码将失败。next
为空。

您在说哪一行?您将传递什么作为第二个参数到list\u entry?您的第三个参数也没有意义,因为它没有在我可以看到的任何地方声明…@Jason
list\u entry
可能是一个宏
head
struct area\u control
@melpomene中的成员之一好吧,我认为有宏定义是很重要的……如果元素以正确的方式初始化,linux双链接列表中不能有空值字段
prev
next
。您还可以看到反汇编代码
mov-rax,[rbp+cur_区域];mov rax,[rax]
这些宏定义的
list\u entry
-这些代码运行良好,尽管walue
cur\u area->head。next
为空(根据您问题中的信息)我觉得
cur\u area->head。next
NULL
。它是如何变成空的我不能说。可能是代码其余部分中的一个bug。我会在调试器中更改断点时将其设置为打开。
cur\u area->head.next
可以在这些行中具有任何值,而不会产生致命后果。Bug“null pointer dereference”表示
cur\u area
(不是像您所说的cur\u area->head.hext)为null。调用跟踪也会在错误点显示相同的:%rax=0x0000可能错误消息的生成被强制转换搞混了?你说
cur\u area->head.next
不应该是
NULL
。在调试器中再次运行它并检查值。