I have the following malloc stack trace when I call leaks with the following command:
MallocStackLogging=1 leaks
Leak: 0x15d3cac0 size=256 zone: DefaultMallocZone_0x7b0a000
Call stack: [thread 0xb0468000]: | thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[AggregatorObjCWorkQueue newThreadMainLoop] | -[NSRunLoop(NSRunLoop) runMode:beforeDate:] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSources0 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ | __NSThreadPerformPerform | -[NSObject performSelector:withObject:] | -[AggregatorTask run] | -[ComAppAggregatorApiSystemClientWorkerFactory_$4_$1 run] | -[ComAppAggregatorFrameworkClientSubscriptionSyncer startWithComAppAggregatorApiClient:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry addSubscriptionWithComAppAggregatorQueryQueryXML_Subscription:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry newSyncAndPostWithComAppAggregatorQueryQueryXML_QueryKey:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry writeUpdateWithComAppAggregatorQueryQueryXML_QueryKey:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry writeSubscriptions] | -[JavaUtilTreeMap putWithId:withId:] TreeMap.m:371 | -[JavaUtilTreeMap createNodeWithId:withId:] TreeMap.m:634 | -[JavaUtilTreeMap_Node init] TreeMap.m:1463 | -[IOSObjectArray initWithLength:type:] IOSObjectArray.m:42 | calloc | malloc_zone_calloc
Can someone help me understand this call stack trace from malloc?
i.e to break down the question:
1. How is the stack trace ordered?
Class1 Method1 | Class2 Method2 | Class3 Method3:
What do these signify?
2: What do the positive and negative signs before the object description mean?
-[class method] | +[classs method]
3: Which of these is actually the one which leaked?
I am not able to pin down exactly which object/part of the stack trace is leaking.
Any links to documents would be great!
It’s much easier to use the Leaks instrument (in the Instruments app) to look at stack traces in its Extended Detail pane.
But here’s how to analyze your stack trace. First, replace every instance of
|with a newline:Question 1: The oldest stack frame is on top and the youngest is on the bottom. So
thread_startcalled_pthread_start, which called__NSThread__main__, which called-[NSThread main], and so on.Question 2: The function named
-[NSThread main]is the function that implements the instance methodmainof theNSThreadclass. The Objective-C compiler can generate functions with names (like-[NSThread main]) that you can’t write out literally in your source code.For a class method, the function name starts with a
+instead of a-. So the class methodallocon theNSObjectis implemented by a function named+[NSObject alloc].Question 3: The stack trace you posted shows the stack trace at the moment the leaked object was allocated. No part of that stack trace is necessarily “actually the one which leaked”.
You need to understand what it means for an object to be leaked. It means there are no global variables or local variables (on the stack) that point to the leaked object, or point to an object that points to the leaked object, or point to an object that points to an object that points to the leaked object, etc. etc. etc. Since there is no chain of pointers that start from a global or local variable (a “root pointer” as we say in the biz) and lead to the leaked object, your program has no way of accessing the object, even though it’s still allocated.
So why did it become leaked? Because it wasn’t released before the last of those chains from a root pointer to your object was broken. It became leaked because a function that should have been called – the release function – was not called. It should have been called some time after the object was allocated. Since the leaks tool only shows you the stack trace when the object was allocated, it may not give you enough information to figure out where that missing release should go.
Which brings us back to the Leaks instrument in the Instruments app. The Leaks instrument also can’t show you the exact spot where you should have released, but it can show you the stack trace of every time the object was retained, released, and autoreleased. These additional stack traces may help you figured out why the object was leaked. Instruments also formats the stack trace more nicely than the leaks command-line tool. And if you have a network of leaked objects, Instruments can show you that network graphically, which may make it easier for you to understand why your app is leaking objects.
Apple has posted a bunch of developer videos, some of which introduce you to Instruments. I don’t recall exactly which video or videos talk about leak detection, but I know at least one of them does. Start with the WWDC 2012 videos and work your way back.
EDIT
The WWDC 2012 video “Session 409 – Learning Instruments” talks about using the Leaks instrument starting around 35 minutes in.
The WWDC 2011 video “Session 310 – What’s New In Instruments” talks about using the Leaks instrument starting around 39 minutes in.
It’s definitely mentioned in some of the others too.