【问题标题】:Pointer is pointing to 0x1 - is checking for null valid?指针指向 0x1 - 检查 null 是否有效?
【发布时间】:2012-03-06 03:22:19
【问题描述】:

在我们的一些代码中;我们遇到了分段错误,gdb 堆栈跟踪显示指针指向0x1。我们有 3 个这些分段错误的实例,每个实例都有;指针最终指向0x1

我想“优雅地”从这个错误中恢复;而不是SEGFAULT。我无法检查NULL;因为那将是0。我是否明确检查地址0x1

这是在 Linux 上使用 GCC3.4.2(SLES9 机器)

【问题讨论】:

  • 这是在什么平台上的? (CPU 架构和操作系统。)

标签: c++ c null gdb


【解决方案1】:

是的,你得到一个指向 0x1 的指针的原因很可能是因为你取消了一个指向 null 的结构:

struct some_struct* ptr = NULL;
char blah = ptr->foo;

碰巧foo 位于结构开头的偏移量 1 处。所以数学最终是*(0+1)

【讨论】:

  • 可能是这样,但您仍然应该检查ptr != NULL,而不是&ptr->foo != 0x01
【解决方案2】:

我想从这个错误中“优雅地”恢复,而不是 SEGFAULT。我无法检查 NULL,因为那将是 0。我是否明确检查地址 0x1

可能不是最好的主意。

恢复的方法(从技术上讲,恢复是不合理的,你确实需要阻止它)将假设 0x1NULL 一样糟糕,而不是尝试使用在这种情况下,类似于:

if ((p == 0) || (p == 0x1))
    return;
// Otherwise use p.

但是,我非常犹豫是否称其为优雅。 正确 要做的事情是找出导致指针设置为无效值的原因并修复它。这特别合适,因为一段代码足够狡猾,可以生成1 的指针值,也可能足够狡猾,可以生成2,或任何其他无效指针。

检查1 类似于在有人不断打你的头时用止痛药止头痛。您可以服用该平板电脑来缓解头痛,但肯定最好解决问题的根本原因(即,阻止那个人打你的头部)。

【讨论】:

  • 我同意在此之前修复它。只是想指出(假设页面大小为 4k)检查(ptr < (void*)0x1000) 可能会更好。或者使用 PAGESIZE #define(如果存在)。因为你可以很确定0x0 的页面不会被映射。
  • NT 上所有值 不是(您可以映射 VA 0x0,从而导致大量有趣的 EoP 漏洞利用)
  • 好吧,编辑后的问题指出的是 Linux 而不是 NT,但这两种方式都无关紧要。您仍然应该解决根本原因,而不是试图从影响中恢复。
  • +1,除了空检查之外,不要尝试做任何聪明的事情来检查指针的实际值
  • 实际上,我不打算发表评论,但是,由于您劫持了我的答案 :-),C99 在 6.3.2.3 中声明:“整数可以转换为任何指针类型。除非之前指定,结果是实现定义的,可能没有正确对齐,等等等等”。所以它不是不允许的,只是实现定义的。
【解决方案3】:

当您通过将空指针传递给没有为空参数分配特定含义的代码段而违反接口约定时,就没有“优雅地”恢复这样的事情。可能无效的程序状态的数量没有限制,您可能已经在某处调用了未定义的行为。

由于我过去已经在 SO 上写了很多关于这个主题的文章,所以我会给你一个链接到我的论文:

In either C or C++, should I check pointer parameters against NULL/nullptr?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2020-03-29
    • 1970-01-01
    • 2011-09-05
    相关资源
    最近更新 更多