c语言 - 为什么我的 if 没有捕获此空指针取消引用?



我正在处理一个内核模块,该模块在插入时会导致空指针解引用。我已经在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,所以我可以尝试找出原因,我只是想知道为什么我的调试打印也会导致错误。

这种情况使我感到困惑;我明确检查了cc->node是否为而不是null,我认为这应该可以防止这种错误(基于这样的答案(。解引用操作是针对c(因为根据我的理解,c->member等价于(*c).member(和c->node。所以为什么,如果cc->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);

最新更新