0xDEADBEEF等效于64位开发?

时间:2009-08-11 01:24:19

标签: c++ debugging 64-bit defensive-programming

对于32位系统的C ++开发(无论是Linux,Mac OS还是 Windows,PowerPC或x86)我初始化了指针 否则将是不确定的(例如他们不能立即 得到一个合适的价值)像这样:

int *pInt = reinterpret_cast<int *>(0xDEADBEEF);

(为了节省打字,通常是DRY右侧 在一个常数,例如BAD_PTR。)

如果pInt在获得适当的值之前被解除引用 它会在大多数系统上立即崩溃(而不是 当一些内存被覆盖或继续时,崩溃很久 进入一个很长的循环)。

当然行为取决于潜在的 硬件(从奇数获得4字节整数 来自用户进程的地址0xDEADBEEF可能是完美的 有效),但崩溃已经100%可靠的所有 我迄今为止开发的系统(Mac OS 68xxx,Mac OS PowerPC,Linux Redhat Pentium,W​​indows GUI Pentium,W​​indows 控制台奔腾)。例如在PowerPC上它是非法的(总线 从一个奇数地址获取一个4字节的整数。

在64位系统上,这有什么好处?

12 个答案:

答案 0 :(得分:68)

0xBADC0FFEE0DDF00D

答案 1 :(得分:53)

According to Wikipedia,BADC0FFEE0DDF00D用于IBM RS / 6000 64位系统,以指示未初始化的CPU寄存器。

答案 2 :(得分:26)

目前大多数64位系统只允许使用地址空间中最低的2 48 -2 52 位;地址的高位必须为全零。一些芯片(例如amd64)也允许你使用最高 2 48 -2 52 。超出这些范围的地址不能映射到可访问的内存;硬件根本不允许它。

因此,我建议你使用一个接近2 63 的值,它远离任何一个可能可用的空间。如果前四个十六进制数字是7ff8,则该值将是双精度浮点NaN,这很方便。所以我建议的可爱的十六进制短语是0x7FF8BADFBADFBADF。

顺便说一下,你真的不想使用接近于0的值,因为这使得很难告诉 offset 取消引用NULL - 例如,结构成员访问 - 来自对毒药模式的解除引用。

答案 3 :(得分:24)

通常,完全您编写的模式并不重要,重要的是您可以识别模式以确定问题发生的位置。碰巧在Linux内核中经常选择这些,以便在解除引用地址时可以捕获它们。

include/linux/poison.h查看Linux内核。此文件包含许多不同内核子系统的不同中毒值。没有一种合适的毒药价值。

此外,您可以检查Linux内核源代码树中的每个体系结构包含文件,以获取有关特定体系结构所用内容的信息。

答案 4 :(得分:14)

我假设你已经打折了NULL(即没有类型转换的0)。这绝对是最安全的选择,理论上,有效指针可以指向内存地址0xDEADBEEF(或任何其他非NULL内存地址)。

答案 5 :(得分:13)

0xDEADBEEFBAADF00D可能有用。

答案 6 :(得分:8)

我没有一个很好的选择,但是你可以使用list of hex words来制作你的短语。

答案 7 :(得分:5)

我认为两个0xDEADBEEF就足够了。

答案 8 :(得分:3)

我看到声称NULL的几个答案是一个不错的选择,但我不同意。

NULL通常用作函数的有效返回值。它表示故障返回或未知值。这与“未初始化的指针”不同。

在代码上使用调试器并看到NULL会留下两种可能性:指针从未被初始化或者内存分配失败。

将未初始化的指针设置为0xDEADBEEF或64位等效指示意味着NULL指针指示有意值。

答案 9 :(得分:2)

当然,这取决于操作系统和环境。我不认为0xDEADBEEF在任意32位系统中也不一定是坏指针。

实际上,任何现代操作系统都应该访问 - 保护进程内存的前几页,因此NULL应该是一个好的无效指针值。方便的是,它已经为您预先定义。

答案 10 :(得分:0)

0x42可以同时适用于32位和64位吗? (它应该仍然会触发崩溃,因为它足够接近NULL指针,并且考虑到它相当大,很可能你不会在结构指针为NULL的常规解引用中使用它。)

答案 11 :(得分:0)

由于我工作的系统基本上运行在x86_64平台上,因此我使用的值是:

0xDEADBEEFDEADBEEF

共鸣是

  • 在x86_64平台上,当前实现中仅低阶48位用于虚拟内存地址,这意味着> 2 ^ 48的任何值都应起作用:https://en.wikipedia.org/wiki/X86-64
  • 由于0xDEADBEEF已经以32位的这种功能而闻名,所以64位的0xDEADBEEFDEADBEEF更加“向后兼容”