使用GCC C处理AIX上的空指针

我们有一个用C编写的代码,有时候不能很好地处理零指针。

该代码最初是在Solaris上编写的,这样的指针会导致分段错误。 不理想,但比耕作更好。

我们的经验是,如果从AIX上的空指针读取,则得到0.如果使用xlc编译器,则可以添加选项-qcheck=all来捕获这些指针。 但我们使用gcc(并希望继续使用该编译器)。 gcc提供这样的选择吗?

gcc提供这样的选择吗?

我怯懦地自愿回答否,但事实并非如此 。 虽然我不能引用缺少有关gcc和运行时NULL检查的信息。

你正在解决的问题是你试图在一个编写得不好的程序中更多地定义未定义的行为。

我建议您咬紧牙关并切换到xlc或手动将NULL检查添加到代码中,直到找到并删除了不良行为。

考虑:

  • 使宏空以检查指针
  • 在指针赋值后添加该宏
  • 将该宏添加到接受指针的函数的入口点

删除错误后,您可以开始删除这些检查。

  1. 请帮助我们,并为您的代码添加适当的NULL检查。 通过仅在需要时检查NULL ,而不是让编译器在任何地方执行检查,您不仅可以略微提高性能,而且您的代码将更易于移植到其他平台。

    并且我们没有提到这样一个事实:您将更有可能打印出正确的错误消息,而不是让编译器删除一些难以理解的堆栈转储/源代码位置/错误代码,这些代码根本无法帮助您的用户。

  2. AIX使用NULL页面的概念。 实际上, NULL (即虚拟地址0x0 )被映射到包含一大堆零的位置。 尽管遇到NULL指针,这允许字符串操作代码等继续。

    这与大多数其他类Unix系统相反,但它并没有违反C标准,后者认为取消引用NULL是一种未定义的操作 。 但是在我看来,这已经被打破了:它需要一个会剧烈崩溃的应用程序并将其变成一个无声地忽略编程错误的应用程序,可能会产生完全错误的结果。

  3. 据我所知,GCC没有办法解决根本破坏的代码。 即使是历史上支持的模式,例如可写字符串文字,也在较新的GCC版本中逐渐被淘汰。

    在使用内存调试选项(如-fmudflap时可能会有一些支持,但我真的不知道 – 在任何情况下都不应该在生产系统中使用调试代码,尤其是强制破坏代码才能工作。

结论:我认为你不能避免添加显式的NULL检查。

不幸的是,我们现在提出了一个基本问题: 应该在哪里添加NULL检查? 。 我想如果您在发现问题时添加显式检查,编译器会不加选择地添加此类检查。

不幸的是,没有Valgrind对AIX的支持。 如果您有现金,您可能希望查看IBM Rational Purify Plus for AIX – 它可能会捕获此类错误。

也可以在测试系统上使用xlc在其他所有内容上使用gcc ,但遗憾的是它们并不完全兼容。