我正在处理一个内核模块,该模块在插入时会导致空指针解引用。我已经在swnode.c中追踪到了这个错误(不是内核模块的一部分,但由模块调用(:
static struct fwnode_handle *
software_node_get_next_child(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
struct swnode *p = to_swnode(fwnode);
struct swnode *c = to_swnode(child);
if (!p || list_empty(&p->children) ||
(c && list_is_last(&c->entry, &p->children)))
return NULL;
if (c) {
c = list_next_entry(c, entry);
if (c->node)
pr_info("child node named %sn", c->node->name);
} else {
c = list_first_entry(&p->children, struct swnode, entry);
}
return fwnode_handle_get(&c->fwnode);
}
我添加了用于调试的pr_info("child node named %sn", c->node->name);
调用,这一行导致空指针取消引用。在此之前,错误发生在return fwnode_handle_get(&c->fwnode)
上,这导致了一个错误,抱怨我在NX内存中执行东西;很明显,c->fwnode为NULL,所以我可以尝试找出原因,我只是想知道为什么我的调试打印也会导致错误。
这种情况使我感到困惑;我明确检查了c
和c->node
是否为而不是null,我认为这应该可以防止这种错误(基于这样的答案(。解引用操作是针对c(因为根据我的理解,c->member
等价于(*c).member
(和c->node
。所以为什么,如果c
和c->node
是而不是null,则只应评估pr_info
调用,这会导致null指针解引用吗?
编辑:
亲密的选民需要更仔细地阅读问题和线索。此问题不是由拼写错误引起的。原始示例中丢失的大括号(后来经过编辑以包含它们(不是问题的原因。
您的代码
if (c)
c = list_next_entry(c, entry);
if (c->node)
pr_info("child node named %sn", c->node->name);
else
c = list_first_entry(&p->children, struct swnode, entry);
相当于
if (c) {
c = list_next_entry(c, entry);
}
if (c->node) {
pr_info("child node named %sn", c->node->name);
} else {
c = list_first_entry(&p->children, struct swnode, entry);
}
因此,无论c
是否为NULL
,都将对c->node
进行评估。
添加大括号以检查c
是否有效。
if (c) { /* add a brace */
c = list_next_entry(c, entry);
if (c->node)
pr_info("child node named %sn", c->node->name);
} /* add a brace */
else
c = list_first_entry(&p->children, struct swnode, entry);