Debugging Memory Corruption in Game Development
October 16, 2008 Page 4 of 6
Small integers (in the range 0 to 10000) are usually counters or enums. If you see the value incrementing or decrementing evenly, then that indicates a counter.
If you see it oscillate between a few fixed values, then it is probably some kind of state variable.
Does this small integer seem to match anything in the game at the time of corruption? Some possibilities:
- Level number
- Weapon number
- Button Pressed
Try to find some correlation between what is going on the game, and the value of corruption.
As numbers get larger, the number of uses for them decrease. It's unlikely that you will be managing groups of over 100,000 items. If you have a large integers that look like they are counting, then you should consider what it might be counting.
Consider then if it might actually be a pointer, or a code address, and not an integer value at all.
FFFFF3A2 of A2 F3 FF FF
Negative integers start with ‘F's rather than ‘0's.
Integers are generally used for counting things. If you have a negative integer, then that greatly narrows down the range of things it might be used for.
Some code uses the negative form of an integer as a single kind of flag to change the behavior of the code, avoiding the need to have an additional flag.
Negative numbers are also sometimes used as error codes. Some functions take a pointer as a parameter, and then return the error code in the location pointed to by the pointer. If the pointer is incorrect, that will lead to memory corruption with a negative number.
Magic Hex Numbers
DEADBEEF or EF BE AD DE
A magic hex number in the context of debugging is a hex value that has been specifically chosen by the programmer to be visible in the debugger.
The numbers are also chosen so that using it inadvertently will maximize the chances of that use causing an error, and hence alerting the programmer to the illegal usage.
The most common use is in initializing a block of memory to certain values both when it is allocated and when it is freed. This both makes the block visible in the debugger (in the memory window), and also fills it with values that the programmer should notice if they are used either before the memory has been initialized correctly, or if the memory continues to be used after it has been freed.
Common Magic Hex Numbers are:
Use of magic numbers varies by platform. Often developers use their own magic numbers, and they tend to prefer those that can be read aloud, such as DEADBEEF.
474E5089 or 89 50 4E 47 or ‰PNG
Frequently asset files are identified by a four byte (partially) ASCII string that indicates the file type in some human readable way. It's quite unlikely that this will find its way into a single word corruption, but it's worth looking in the ASCII column in the memory window, just to check if this is the case, since if you recognize this, it should hopefully point you directly at the culprit.
00434150 or 50 41 43 00
Your program usually occupies a relatively small amount of the available four gigabyte address range of a 32-bit pointer. Hence, pointers usually fall within a recognizable range.
Under Win32, your executable starts at address 00400000 (4MB from the start of it's virtual address space) so function pointers, and pointers to static data will often start with 004 (and 005, 006 etc as your program increases in size).
On the PS2, your executable start at 00100000 (1MB), so pointers will start with 001, 002, etc.
Function pointers are an unlikely candidate for corruption data, so if you see a pointer like this, it's more likely a pointer to some static data.
The most common type of pointer to static data that is passed around is a pointer to a string. If it looks like you have a pointer in your corruption data, then try following it and see if it points to a recognizable string.
Depending on your platform, pointers may be more likely to be word aligned. On the PS2, pointers to code or any word sized data must be word aligned. The PC allows all data referencing at the byte level.
9D29F113 or 13 F1 29 9D
When you look through the memory occupied by your game, you will find surprising little data that looks random. There are usually lots of zeros, and where the data is more closely packed, certain bytes or patterns predominate.
So when you find a number that looks random, it almost certainly has some meaning. Here are some of the things it could be.
A floating point number - as mentioned previously, a floating point number with several significant digits will look kind of random. The constant pi (3.141592654) comes out as 40490FDB - which looks random.
A checksum - if your code uses a checksum, such as CRC32, for some reason, such as identifying assets, then this could be a stray one. If you have the capability, then try seeing what string generates this checksum.
Compressed data - well compressed data should look random. It's unlikely that it would end up in a single word of corruption, but possible.
Text - It looks random at first sight, but if the bytes are mostly in the range 0×30 to 0×7F, then it is quite possible that it is a fragment of a string. See what it says in the ASCII column of the memory window.
Page 4 of 6