0xDEADBEEF equivalent for 64-bit development?

41

For C++ development for 32-bit systems (be it Linux, Mac OS or Windows, PowerPC or x86) I have initialised pointers that would otherwise be undefined (e.g. they can not immediately get a proper value) like so:

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

(To save typing and being DRY the right-hand side would normally be in a constant, e.g. BAD_PTR.)

If pInt is dereferenced before it gets a proper value then it will crash immediately on most systems (instead of crashing much later when some memory is overwritten or going into a very long loop).

Of course the behavior is dependent on the underlying hardware (getting a 4 byte integer from the odd address 0xDEADBEEF from a user process may be perfectly valid), but the crashing has been 100% reliable for all the systems I have developed for so far (Mac OS 68xxx, Mac OS PowerPC, Linux Redhat Pentium, Windows GUI Pentium, Windows console Pentium). For instance on PowerPC it is illegal (bus fault) to fetch a 4 byte integer from an odd address.

What is a good value for this on 64-bit systems?

c++
debugging
64-bit
defensive-programming
asked on Stack Overflow Aug 11, 2009 by Peter Mortensen • edited Dec 28, 2010 by Zain Shaikh

12 Answers

69

0xBADC0FFEE0DDF00D

answered on Stack Overflow Aug 11, 2009 by chaos • edited Aug 2, 2010 by chaos
53

According to Wikipedia, BADC0FFEE0DDF00D is used on IBM RS/6000 64-bit systems to indicate uninitialized CPU registers.

answered on Stack Overflow Aug 11, 2009 by Thomas Owens
26

Most current 64-bit systems let you use only the lowest 248–252 bits of the address space; higher bits of the address must be all-zero. Some chips (e.g. amd64) also let you use the highest 248–252. Addresses outside these ranges cannot ever be mapped to accessible memory; the hardware simply won't allow it.

I therefore recommend you use a value close to 263, which is nowhere near either of the possibly-usable spaces. If the leading four hex digits are 7ff8, the value will be a double precision floating-point NaN, which is convenient. So my suggested cute hexadecimal phrase is 0x7FF8BADFBADFBADF.

By the way, you really don't want to use a value close to 0, because that makes it hard to tell an offset dereference of NULL — a structure member access, for instance — from a dereference of the poison pattern.

answered on Stack Overflow Aug 2, 2010 by zwol • edited Aug 3, 2010 by zwol
25

Generally it doesn't matter exactly what pattern you write, it matters that you can identify the pattern in order to determine where problems are occurring. It just so happens that in the Linux kernel these are often chosen so that they can be trapped if the addresses are dereferenced.

Have a look in the Linux kernel at include/linux/poison.h. This file contains different poison values for many different kernel subsystems. There is no one poison value that is appropriate.

Also, you might check per-architecture include files in the Linux kernel source tree for info on what is used on specific architectures.

answered on Stack Overflow Aug 2, 2010 by Noah Watkins • edited Jun 24, 2012 by nkr
14

I'm assuming you've already discounted NULL (i.e. 0 without the typecast). It's definitely the safest choice, as, in theory, a valid pointer could point to the memory address 0xDEADBEEF (Or any other non-NULL memory address).

answered on Stack Overflow Aug 11, 2009 by Michael Koval
13

0xDEADBEEFBAADF00D might work.

answered on Stack Overflow Aug 11, 2009 by Joshua • edited May 31, 2012 by Peter Mortensen
8

I don't have a good choice for you, but here's a list of hex words that you can use to make your phrase.

answered on Stack Overflow Aug 11, 2009 by Ned Batchelder
5

Two 0xDEADBEEFs should be enough, I think..

answered on Stack Overflow Aug 2, 2010 by LostMohican • edited Apr 27, 2011 by Peter Mortensen
3

I see several answers claiming NULL is a good choice, but I disagree.

NULL is often used as a valid return value from functions. It indicates a failure return or an unknown value. This is a different meaning than "uninitialized pointer."

Using a debugger on the code and seeing NULL would then leave two possibilities: the pointer was never initialized or it had failed a memory allocation.

Setting the uninitialized pointer to 0xDEADBEEF or the 64-bit equivalent means that a NULL pointer indicates an intentional value.

answered on Stack Overflow Aug 11, 2009 by Zan Lynx
2

It depends on the OS and the environment, of course. I don't think 0xDEADBEEF is necessarily a bad pointer in an arbitrary 32-bit system, either.

Realistically, any modern OS should be access-protecting the first few pages of process memory, so NULL should be a good invalid pointer value. Conveniently enough, it's already pre-defined for you.

answered on Stack Overflow Aug 11, 2009 by Mark Bessey
1

0x42 could work on both 32bit and 64bit ? (It should still trigger a crash since it is close enough to the NULL pointer, and given that it's rather large, chances are you would not have it within a regular dereference of a structure field with the structure pointer being NULL).

answered on Stack Overflow Aug 11, 2009 by Andrew Y • edited Aug 13, 2009 by chaos
1

As the system I worked on basically runs on x86_64 platform, the value I use is:

0xDEADBEEFDEADBEEF

Reasons are:

  • On x86_64 platform, only the low-order 48 bits are used for virtual memory address in current implementation, meaning any value > 2^48 should work: https://en.wikipedia.org/wiki/X86-64
  • As 0xDEADBEEF is already very well known for this purpose in 32bit, 0xDEADBEEFDEADBEEF in 64bit is just more 'backward compatible'
answered on Stack Overflow May 28, 2019 by Baiyan Huang • edited Jul 3, 2019 by Baiyan Huang

User contributions licensed under CC BY-SA 3.0