Symbian Security Studio

About symbian software programming ,security analysis and other things about symbian.

Saturday, October 27, 2007

Tracking down memory leaks

Tracking down memory leaks

Memory management is a key point in embedded development and so it with with Symbian OS which is a lot stricter than other open operating system on this point. While this not a real big issue for a game or utility application (memory while be taken back by the system once you exit the application), it is a crucial for a background running task to avoid these leaks or the user may have to reboot his phone every other day. Note that in any case, having your application leaking some memory will prevent you from obtaining the Symbian Signed certification.


The symptom


The application works fine (well, this point is not mandatory, it may be completely bugged as well ;-) ) on the phone and emulator. But, when running it on the emulator - and only on it - an error message pops-up when you close the application:


MemLeakError-2.png


This popup window is not really user-friendly but contain useful information: the name of the application and the address of the memory block that has been leaked. In the exemple above, the application name is Armori and the leaked block is at address 0x1416fd04.


Step 1: Get the memory segment


We are now assuming that you use Nokia / Metrowerks Codewarrior (any version / edition will do it) but Microsoft VC++ / .Net user should have all the tools required, only the screenshot will differ.


Put a breakpoint at the beginning of your AppUi ConstructL method (or of the document one if you do significant processing there). Restart your application under the debugger. You should not have modified and recompiled the code or the memory address you got in the popup probably won't be valid anymore. When the debugger stops, note the memory segment that is used by the application. If you are lucky, the memory segmend will be the same than the one you got in the error window. This is the case below where all address are in the form 0x1416yyyy:


MemLeak-Code1-2.png


Now open a memory window (right-click anywhere in the code window and select View Memory) and enter the memory address we are tracking. In our case, this is obviously 0x1416fd04 but this is not always the case. Here is how you can get the address to track:
- take the first four digits from the memory segment (ex: the one from your AppUi instance), here 1416.
- take the last four digits from the popup window (here fd04).


During my debugging process, I always had two choices and depending on the execution I had to use indifferently 0x1416fd04 or 0x1772fd04.


After entering the tracked address, the memory window shall only display some uninitialized data as the memory block has not yet been allocated by the app:


MemLeak-Memory1.png


If some data is displayed in the memory window then:
- you have put the breakpoint too far in the execution, put it at an earlier step of your processing
- or you have made an error in the memory segment. Check the address in the memory window.


Step 2: Get the leaked data


Now, let's check what the leaked buffer contains: add a breakpoint at the beginning of your AppUi destructor and make a first run of the application. When you close the app, this breakpoint will be reached and the memory window shall display the leaked block:


MemLeak-Memory1b.png


I am a lucky guy: the memory dump display the name of a string found in my settings file... [1]


It is now time to put breakpoints to try to find where this block has been allocated. Put some before all the treatments that you have just coded (that's why you should always try to fix a leak when you detect it) and/or various critical points of your application (the ConstructL of most important object is generally a good choice and so are the HandleCommandL and HandleKeyEventL/OfferKeyEventL primitives). In my case, I will just focus on the construction of my application as the settings file is read at the initialisation of the engine.


Restart the application under the debugger (don't forget to modify the address segment to watch in the memory window).


Step 3: Track the execution


We now have to find where the leaked block is allocated. Unless you are working on a very small application, a little bit of time and several runs of the application will be necessary. First, you should do it roughly to indentify during which phase the leak occur: during the creation of a view, during the construction of the engine, when the user request a specific action....


To do so, when you reach a breakpoint, don't try to step into each statement but just step over them and watch the change in the memory window. Nothing should happen until the faulty treament is executed and the allocated block will then appear in red:


MemLeak-Memory2.png


In my case, this occured during in a custom XML parser that was used for processing the ini file: MemLeak-Code2b-2.png


I now know that the processing within the readXMLFile primitive caused the memory leak. I add some breakpoints in other keypoints from this primitive, in my case this will be primitives called parseElement, parseCdata and parseAttribute. I restart the whole process to check which one did allocate the buffer, etc....


Two more runs and I finally spotted the bug, and could fix it :-).


Conclusion


This article briefly introduced you one methodology that can be used to track memory leak. Symbian OS also offers some macros that can be used to track down most simple cases automatically (check Memory Leak Tool) but they cannot always be used when allocated data have to stay through the whole life of the application.


In a general manner, fixing memory leak is a complex and lengthy case. The exemple above may look simple but it is only a short summary of a real life case (one of the worst case actually for tracking leaks, as we just got a big amount of multi-platform code to port on Symbian OS and the leak occured in some callbacks triggered by a loop,etc...). It actually took me about half a day just to identify and correct this leak. So, if you spot a leak in the code you write, just fix it immediately. You will have to do this anyway and the sooner you do it the less time you will need as the leak probably occured in something you just modified.


It also may be worth reading the How to track down memory leaks document published by Forum Nokia which present some further details on the Step 1, to get the memory segment used by the application.


[1] Note that in the first memory view, the memory was filled with 0xAF bytes (meaning memory not allocated) and that most of the memory is now 0xDE bytes (memory has been correctly deallocated).














AttachmentSize
MemLeak-Code1.png14.94 KB







> Tracking down memory leaks





Another good tip, if the memory adress is this predictable, is to at the destructor breakpoint, typecast the memory address to a CBase* in your debugger watch window.


Add a watch: (CBase*)(0x1428f900)


And, if the orphaned cell is a subclass of type CBase, you will be able to unfold it in the watch window, and see its real type.





> Tracking down memory leaks





Hi Eric,


Indeed a good article, only one thing in mind.


When i access the internet (wap etc..) through "Services" on the emulator it gives alloc error on exit.


Similarly any app that accesses the internet gives alloc errors on exit on the emulator (but not on device).


Why so?


And can something be done abt such apps regarding coding so that that alloc does not come up?


Thanks.




> Tracking down memory leaks





Symbian Hooklogger should do the trick?


http://www.symbian.com/developer/downloads/tools.html#HookLogger




Tracking down memory leaks




Hi


Its very nice way of finding out memory leak... but i am facing some problem.


I found that leak is occuring at 0x372B0244 this address and i found that the module with memory block of same address


I did "view memory" and typed 0x372B0244 address....by putting breakpoint at all possible places...and it did not display any msg instead it showed ...i... @ ...
Nothing came in red color...


How can i find out leak...
pls tell me if u have some more tips or logics...


Thanks

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home