HP-UX cc使用默认设置允许空解引用,这在带有RHEL的gcc中可能吗?

HP-UX cc使用默认设置允许空解引用,这在带有RHEL的gcc中可能吗?,c,gcc,rhel,hp-ux,cc,C,Gcc,Rhel,Hp Ux,Cc,从HPUX cc、c89-C编译器手册页: -z不将任何内容绑定到地址零。此选项 允许运行时检测空指针。见 请注意下面的指针。 -Z允许取消对空指针的引用。请参阅上的注释 下面的指针。-z和-z是链接器选项。看见 ld(1)了解更多详细信息。 然后从ld(1): 选项-Z/-Z的默认值是-Z。 这意味着,默认情况下,在HPUX上使用此版本的cc编译的任何取消引用空指针的C程序都会将值读取为0,而不是SEGFULT。RHEL上没有gcc或cc选项。有人知道我如何在RHEL上编译一个C程序,其中

从HPUX cc、c89-C编译器手册页:

-z不将任何内容绑定到地址零。此选项
允许运行时检测空指针。见
请注意下面的指针。
-Z允许取消对空指针的引用。请参阅上的注释
下面的指针。-z和-z是链接器选项。看见
ld(1)了解更多详细信息。
然后从
ld(1)

选项-Z/-Z的默认值是-Z。

这意味着,默认情况下,在HPUX上使用此版本的cc编译的任何取消引用空指针的C程序都会将值读取为0,而不是SEGFULT。RHEL上没有gcc或cc选项。有人知道我如何在RHEL上编译一个C程序,其中包含这样一个选项(允许空引用)?我知道这是一个糟糕的编码实践,我不会用它来创建新代码。谢谢。

这可以通过向程序中添加一些代码来实现

Linux内核有一个最小映射地址,通常大于0,以防止空指针未被检测到。它们通过通常设置为4096(32位)或65536(64位)的system control
vm.mmap_min_addr
来控制这一点。虽然不建议这样做,但您可以将其设置为使用

sudo sysctl -w vm.mmap_min_addr=0
或将其永久设置为:

echo "vm.mmap_min_addr=0" > /etc/sysctl.d/mmap_min_addr.conf
/sbin/sysctl -p
然后,您可以在虚拟地址0处添加空内存页:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

int main(int argc, char **argv) {
  int *p = NULL;
  int n;

  printf(" p = %p\n", p);

  printf(" map = %p\n", mmap(NULL, 4096, PROT_READ,
                             MAP_FIXED | MAP_ANON | MAP_PRIVATE, 0, 0));

  n = *p;

  printf("*p = %d\n", n);

  return 0;
}
参考资料:


    • 这可以通过向程序中添加一些代码来实现

      Linux内核有一个最小映射地址,通常大于0,以防止空指针未被检测到。它们通过通常设置为4096(32位)或65536(64位)的system control
      vm.mmap_min_addr
      来控制这一点。虽然不建议这样做,但您可以将其设置为使用

      sudo sysctl -w vm.mmap_min_addr=0
      
      或将其永久设置为:

      echo "vm.mmap_min_addr=0" > /etc/sysctl.d/mmap_min_addr.conf
      /sbin/sysctl -p
      
      然后,您可以在虚拟地址0处添加空内存页:

      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/mman.h>
      
      int main(int argc, char **argv) {
        int *p = NULL;
        int n;
      
        printf(" p = %p\n", p);
      
        printf(" map = %p\n", mmap(NULL, 4096, PROT_READ,
                                   MAP_FIXED | MAP_ANON | MAP_PRIVATE, 0, 0));
      
        n = *p;
      
        printf("*p = %d\n", n);
      
        return 0;
      }
      
      参考资料:


      很久以前,当我们使用格式化可执行文件时,这个问题的答案取决于可执行文件的“魔法数字”。有0407个可执行文件,0410个,也许还有一些其他的。旧格式(0407)映射了第0页,这意味着可以访问空指针。有链接器选项(可能与HPUX使用的
      -z
      -z
      相同,我不记得了)来说明您想要哪种可执行文件/哪种神奇数字。现在,几乎完全取代了a.out。我可以很容易地想象,有不同风格的ELF(或者更具体地说,ELF头中的选项位)控制着诸如是否应该访问第0页之类的事情。不过,我还没找到任何这种口味的清单。(对于a.out来说,这些风格过去被列在exec(2)或a.out(5)手册页上,但我还没有找到任何与之对应的现代Linux页面。)当时我只是尝试了@mevets提供的mmap解决方案,它在Debian下对我有效。您是否排除了它,因为它需要以root身份运行?(如果是这样的话,我不怪你。)也许可以借助链接器脚本来做你想做的事情。有关它们的信息,请参阅gnu ld手册。我不是ELF格式的专家,但我猜有可能创建一个ELF文件,除了它今天通常设置的所有常规代码和数据段外,还可以在地址0处创建一个0页。因此,可以选择
      ld
      来实现这一点。或者,也可以编写一个程序来获取ELF文件,对其进行修改以添加这样一个段。甚至可能有现成的ELF操纵工具可以做到这一点。(或者,正如我写这篇文章时一位程序员所写的,一个链接器脚本。)很久以前,当我们使用格式化可执行文件时,这个问题的答案取决于可执行文件的“魔法数字”。有0407个可执行文件,0410个,也许还有一些其他的。旧格式(0407)映射了第0页,这意味着可以访问空指针。有链接器选项(可能与HPUX使用的
      -z
      -z
      相同,我不记得了)来说明您想要哪种可执行文件/哪种神奇数字。现在,几乎完全取代了a.out。我可以很容易地想象,有不同风格的ELF(或者更具体地说,ELF头中的选项位)控制着诸如是否应该访问第0页之类的事情。不过,我还没找到任何这种口味的清单。(对于a.out来说,这些风格过去被列在exec(2)或a.out(5)手册页上,但我还没有找到任何与之对应的现代Linux页面。)当时我只是尝试了@mevets提供的mmap解决方案,它在Debian下对我有效。您是否排除了它,因为它需要以root身份运行?(如果是这样的话,我不怪你。)也许可以借助链接器脚本来做你想做的事情。有关它们的信息,请参阅gnu ld手册。我不是ELF格式的专家,但我猜有可能创建一个ELF文件,除了它今天通常设置的所有常规代码和数据段外,还可以在地址0处创建一个0页。因此,可以选择
      ld
      来实现这一点。或者,也可以编写一个程序来获取ELF文件,对其进行修改以添加这样一个段。甚至可能有现成的ELF操纵工具可以做到这一点。(或者,正如我写这篇文章时一位程序员所写的,一个链接器脚本。)