How to track down memory leaks in Symbian C++ using Visual Studio
Published at www.forum.nokia.com on May 12, 2005.
This article presents a method of tracking down a memory leak in cases where the address of that heap allocation keeps changing. The solution consists of the following steps:
- Start the application and run it until it panics.
- Take note of the address that wasn't deallocated. (Assume it's 0x1046a432.)
- Restart the application and run it until it panics. Make sure you run it exactly as you did the first time.
- Again take note of the address. (Assume it's 0x1a52a432.)
- Run it one more time, again until it panics and in exactly the same way.
- Again take note of the address. (Assume it's 0x245ea432.)
- Now looking at the numbers you will find a correlation.
In some cases you will find that the address increases by the same amount with each restart of the application. In the case of the addresses assumed above, the address for the same panic increased from 0x1046a432 to 0x1a52a432, that is, by 0xa0c00000 bytes. Then, the next address was at place of the same increase, that is, 0x245ea432 . So now you know that when you restart the application, there will be a panic at 0x245ea432 + 0xa0c00000 = 0xc51ea432 .
Now view that memory address in the memory window and put a breakpoint in the code just before it panics, that is, in a final destructor call, or some function call that you know is pretty much at the end of the application. When you hit the breakpoint, view what's in that address space. If it looks like some text, then you'll know it is some descriptor that wasn't cleaned up properly. If it contains another address or looks like it's some kind of an object, then try typecasting it in your watcher window like this: (CBase*)0xc51ea432. In many cases, the debugger then will show you what object it is.
However, if the application restarts didn't show a constant increase in the memory address, then try restarting the emulator. After restarting the emulator and the application, run the application until it panics in exactly the same way as previously. If the address is the same as in the previous tests, that is, 0x1046a432, then the next panic will probably be in the address space of the last test round, that is, 0x1a52a432, so try viewing and watching this memory address with the breakpoint enabled when you restart the application.
If that doesn't find the leak, the final thing left is to put a few breakpoints around the code and run the initial tests again, going through about three iterations of panics. But this time in addition to noting the panicking address, also take down the addresses of a few objects that are created in your code, and then try to find any correlation between the known object addresses and the place where the panic occurs. Check for correlations where the first four bits in the address are the same, or perhaps the last four. If you find some correlation, use that to calculate the address of the next failed deallocation.
Process of elimination
If all that doesn't help, you will need to go through your code and disable everything that's allocated, and then enable things step by step until you find the allocation that never gets deallocated.