The library to help to find memory leaks in iOS applicaitons
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Classes
images
memCheck.xcodeproj
CreateClassesSet.rb
DeallocCheck.rb
MainWindow.xib
README.mdown
READMEold.mdown
howToUse.txt
main.m
memCheck-Info.plist
memCheckViewController.xib
memCheck_Prefix.pch

README.mdown

MemCheck helps to find memory leaks in your iOS applications. It can register alloc, retain and release calls for NS-objects and show detail information in console.

That's new edition of documentation. A old edition also works but shouldn't be used.

Connect library

Add files from memCheckLib folder to your project.

add in the tail of your pch file

#define MEMTEST_ON

add in the top of the application: didFinishLaunchingWithOptions: function

#ifdef MEMTEST_ON
[NSObject turnMemCheckOn];
#endif

All actions should be run through parser:

po [parser run:@"your action"]. 

Action consists of arguments, filters and commands. All of them follow each other.

###Arguments### An argument describes which list of objects you want to use.

all - live objects which wasn't deallocated
dead - deallocated objects
heap %Number - live objects for a specified heap
leaks - suggested leaked objects

You can combine several arguments using '+' symbol. For example: heap 1 + heap 2.

###Filters### A filter removes unnecessary objects from list of objects

heap %Number - leave objects for a specified heap
withLiveOwners - leave objects with live owners. An owner of object is who contains a retain property on it.
withoutLiveOwners - remove objects with live owners
withoutOwners - leave objects without owners
withOwners - leave objects with owners
withOwnersLessThan %Count - leave objects with less than a specified number of owners
without %ClassName - remove objects with a specified Class
fromList - leave objects with class from a ClassesSet.m. The file should be generated for your project by a CreateClassesSet.rb script. You should call the script in a root folder of your project:

ruby ./CreateClassesSet.rb ./

Then you should replace base reateClassesSet.rb with a new one.

You can combine several filters after a gap. The result of first filter will pass to the input of second filter. For example:

heap 1 + heap 2 without UIImage withOwnersLessThan 5.

###Commands### A command performs specific actions with a filtered list of objects

markHeap - mark heap
markHeapWithName %Name - mark heap with specified name
print - print information about objects
saveGraph %PathToFile - save a input file for a dot program (http://www.graphviz.org/) to a specified path
showHeaps - show a list of saved heaps

You can combine several commands after a gap. All commands will not change the list of objects. For example:

heap 1 + heap 2 without UIImage withOwnersLessThan 5 print saveGraph /Users/yourname/Documents/dot/mem.txt.

###Using### To call an action you should pause your application in the Xcode debugger and type po [parser run:@"your action"] and press the "Enter". But a result will not be displayed immediately. The action will be started when you press the continue button. To stop automatically when the action will be finished you should add a breakpoint at the end of the parse: function in NSMemCheckParser.m.

###A description of objects### The library wraps an allocated object in NSMemCheckObject. There is a description for one of them:

2011-12-11 11:56:04 +0000 memCheckObject 0x68d0fd0 object 0x68cef80 stack 0x0 DEAD UILabel  
owner (detailDescriptionLabel 2011-12-11 11:56:04 +0000 memCheckObject 0x68c3eb0 object 0x68c3de0 stack 0x68c4050 DEAD DetailViewController  
owner (sceneViewController 2011-12-11 11:56:04 +0000 memCheckObject 0x68be640 object 0x68bf1d0 stack 0x68bf2f0 DEAD UIStoryboardScene  )
)

2011-12-11 11:56:04 +0000 - the allocated time
memCheckObject 0x68d0fd0 - itself pointer
object 0x68cef80 - the pointer to the wrapped object
stack 0x0 - the pointer to a alloc stack of the wrapped object, it can be null
DEAD - that flag says that the wrapped objects is already deallocated
UILabel - the class of the wrapped object

If the wrapped object has an owner that information is displayed below after a "owner" keyword. Information of parent contains additional information at the beginning: detailDescriptionLabel - the name of property in the owner class which reference to the wrapped object

If the owner contains its owner then information about that is displayed below.

If the wrapped object contains 2 or more owners that is displayed shortly:

2011-12-11 19:33:54 +0000 memCheckObject 0x6abe390 object 0x68cfb10 stack 0x0 (0,0) UICFFont  owner 4

To display all owners you should enter an "owners" command for a pointer of wrapped object:

po [0x6abe390 owners]

###Examples###

Print all allocated objects:

po [parser run:@"all print"]

Print the suggested leaked objects which have less than 5 owners:

po [parser run:@"leaks withOwnersLessThan 5 print"]

A most useful command to save information about your leaks:

po [parser run:@"leaks fromList withOwners withOwnersLessThan 5 without UIImage saveGraph /Users/yourname/Documents/dot/mem.txt"]

###Using saveGraph command### A saveGraph command creates a text file. In the above example its name is "mem.txt". To convert the file to a dot file we should run the next script:

dot -Tdot mem.txt -o mem.dot && open ./mem.dot 

It will show a graph with objects, relations between them and marks of heaps.

dot graph pic 1

Timeline and mark of heap is displayed at left part in the picture.

dot graph pic 2

An arrow from the DetailViewController to the UILabel means that an object of DetailViewController contains an object of UILabel. A dotted arrow shows when an object dead. Live objects have a white background, dead objects have a gray background.

The first pointer of object reference to an object of NSMemCheckObject. The second pointer reference on object directly.

There is generated image for memCheck.xcodeproj:

dot graph pic 3

###How the library finds leaks###

The library have two arrays. A memData array contains all allocated objects. A suggestedLeaks contains objects which I think is leaked.

Before a release call in a object I perform the next operations. I scan all retain properties in the object. If the object has one retain count I will put all his properties' object in the suggestedLeaks array. I do that because I make suggestion that programmer forgot add release call in the dealloc method of the object. If I am wrong an added object will be removed from the suggestedLeaks array when it dealloc will be called. In short that means that all objects which owners was deallocated are suggested leaked. Yes that's rough method but in practice it's a perfect filter of unnecessary object. But the library will display some live objects on the top of a graph.

###Using with ARC### Hmm, may be that is useful but I don't know. To allow that set -fno-objc-arc for all library files. For full description please see http://stackoverflow.com/questions/6646052/how-can-i-disable-arc-for-a-single-file-in-a-project.

###Known issues### After run action sometimes you may see the message

The program being debugged hit an ObjC exception while in a function called from gdb.
If you don't want exception throws to interrupt functions called by gdb
set objc-exceptions-interrupt-hand-call-fns to off.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (objc_msgSend) will be abandoned.

press continue to continue action. If action was blocked repeat it.

Library can't register toll-free bridge objects (NSArray, NSDictionary, NSNumber and other).

Library registers objects relation through property only.