0xDEADBEEF - finding what bits of memory changed

In Lisa Simone's book "If I only changed the software, why is the phone on fire?", the first chapter shows the development team of "Hudson Technologies" tackling a common challenge in embedded development. A variable storing the colour of an LED seems to be overwritten by data from a structure that belongs in the memory location before it. Oscar, the new department manager who is also an experienced developer, recommends that they 'dead beef it'.
'Dead beef' is one of many short phrases and words that can be constructed from the available alphanumeric characters in the hexadecimal numbering system. Using an integrated development environment it is possible to fill the SRAM memory of a target microcontroller with such a recognisable pattern prior to executing the application code. When the target is then later stopped, either by halting it or as a result of reaching a breakpoint, a quick look at the memory window is all that is needed to see which memory locations have changed. This is an excellent method to see if:

• a stack has overflowed
• the code is writing beyond the end of an array
• a buffer is being overfilled
• or a data memory pointer is resulting in writes to unexpected memory locations.

In the following example we will take a look at how a pattern can be written into volatile memory for debugging purposes using iSYSTEM's winIDEA development environment. As debug hardware we were using the iTAG.2K debugger and an Atmel SAMD21 MCU, but this technique is appropriate for all debug hardware and target MCUs. We already had a project open, had checked it was functional, and took these next steps to "0xDEADBEEF" our SRAM:

1. If it is not already available, open the 'Memory' view from the winIDEA menu as follows: View -> Memory... (or just press Alt + F6).

2. The memory window should look something as shown here. Typically SRAM is filled with random values, although you might see the remnants of variable contents from a previous execution of the application.

3. The default way of displaying the memory contents is as individual bytes. As we are working on a 32-bit ARM Cortex machine, and since we wish to use the pattern "0xDEADBEEF", which is a 32-bit pattern, we need to change the way the memory contents is displayed from 8-bits to 32-bits. Start by simply right-clicking with the mouse in the memory window to open a context menu:

4. Click on 'Display Mode...' and you will be offered a dialogue box through which you can change the manner in which the memory contents is displayed. We will change 'Display Unit Size' here from '1-Byte' (left) to '4-Bytes' (right):

5. After clicking 'OK', our memory display should now be showing the memory contents in 32-bit, instead of 8-bit, blocks, as shown below:

6. Next, the filling of dead beef! Right-click the memory window again to open the context menu, then select 'Fill...', as below:

7. In the following dialogue window we can now define:

- the pattern we wish to fill the memory with (Value)
- the address from where the pattern should start being written in memory (From Address)
- the size of the area to be written (Size)

In this example, we are writing the pattern '0xDEADBEEF' to addresses 0x20000000 onwards for 4096 x 32-bits of memory space. Click on 'Fill' and the dialogue will close and the desired memory space written.

8. Returning to our memory window, we now see that the desired pattern is present in all the defined memory locations:

9. The last step is to execute the application code, halt the MCU or hit a breakpoint, and review the content of the memory window once more. By scrolling down through the memory, we can see which locations have been touched by the application code, and which ones haven't. Looking at the results below, we can see that address 0x20002BD0 has been modified, but address 0x20002C10 has not.

Gotchas: The fill function in the memory window can only write a pattern that is as large as the display mode of the window. If you are only seeing the last byte of your pattern being written to the chosen memory space, perhaps you are still in the '1-Byte' display mode!


This is a really helpful technique that quickly shows what the code it actually doing - especially useful during those drawn-out arguments about data pointers, NUL bytes and stack usage. Remember, the CPU is only doing what the compiler said your source code said it should do!


Happy BugHunting!