未初始化的内存用于调试的常见值是什么?

很久以前我学会了用0xDEADBEEF填充未使用/未初始化的内存,以便在调试器或崩溃报告中,如果我看到该值,我知道我正在查看未初始化的内存。 我从崩溃报告中看到iOS使用0xBBADBEEF

人们使用了哪些其他创造性价值观? 任何特定的价值观都有任何特定的好处吗?

变成单词的价值最明显的好处是,至少在大多数人中,如果单词是用他们的语言,那么他们很容易突出,因为某些严格的数值不太可能突出。

但是,也许有其他理由选择数字? 例如,奇数可能会使处理器(68000)崩溃,例如在某些内存访问时崩溃,因此最好选择0x0BADBEEF超过0xBADBEEF0 。 他们的任何其他值(可能是处理器特定的)是否具有使用未初始化内存的具体好处?

一般来说,您需要一个在解释为整数,指针或字符串时不太可能发生“工作”的值。 所以,这里有一些限制:

  • 不要使用目标体系结构中最小“常规”对齐的倍数值。 对于x86,那是4(字节),所以没有可被4整除的值。这确保了如果将值解释为指针,那么它显然是不正确的。 如果您使用的是非x86体系结构,则甚至可以使用一个值,如果将其用作指针,将导致对齐陷阱。

  • 不要使用可能合理地为小(正或负)整数的值。 C程序中典型的“int”变量永远不会超过1,000左右,因此不要使用小数字作为空数据填充。

  • 请勿使用完全由有效ASCII字符组成的值。 确保高位设置中至少有一个字节。 这些天,您要确保它们不是有效的UTF-8或UTF-16值。

  • 值中没有任何零字节。 有太多的情况下,这将有助于防止程序崩溃 – 终止字符串,给非int字段一个合理的值,等等。

  • 不要使用单个(或两个)字节值,反复重复。 具有全字长度模式可以更容易地确定您的野生指针最终指向它的位置,至少缩小哪些操作从模式的开始偏移它。

  • 不要使用映射到“典型”进程的有效地址的值。 如果设置了最高位,那么在您的进程增长到足以使其成为有效地址之前,通常需要大量的malloc()。

也许不出所料,像0xDEADBEEF这样的模式基本上满足了所有这些要求。

像这样的价值观的一个技术术语是“毒药价值”。

形成英语单词的hex数字称为Hexspeak。 维基百科的Hexspeak文章几乎回答了这个问题编写了许多用于各种事物的已知常量,包括几个用作毒性值/金丝雀/健全性检查,以及其他用途,如错误代码或IPv6地址。


我似乎记得0xBADF00D一些变化。 (也许像你的第二个例子一样重复的字母)。

还有0xDEADC0DE 。 (谷歌搜索我在哪里看到这个使用发现上面链接的维基百科文章)。


hex中的其他英语单词我看过:Java .class文件使用0xCAFEBABE作为幻数(文件的前4个字节)。 作为一个游戏,我想,Jikes JVM使用0xDEADBABE作为健全性检查常量。

显然Java不是0xCAFEBABE的第一个用户。 维基百科说:“ 它最初由NeXTSTEP开发人员创建,作为Peet咖啡和茶的咖啡师的参考 ”,并且他们想到“Java”这个名字之前被开发Java的人们使用。 所以它不是来自Java – >咖啡(如果有其他方式),它只是普通的非女权主义科技文化。 🙁


re:update: 选择一个好的价值 。 对于中毒值(不是错误代码),您希望所有字节都不同而不是0x000xFF ,因为这些可能是错误的单字节存储的最可能值。 这尤其适用于堆栈金丝雀(用于检测缓冲区溢出)或其他检测到未被覆盖的情况非常重要。

你对选择奇数值的猜测很有意义。 在典型过程的虚拟内存布局中不是有效的内存地址是一个很大的优势 。 尽早失败是调试的最佳选择。 无论如何,这可能意味着拥有高位设置是一个好主意,所以0x0...可能不是一个好主意。