iOS libsystem_c.dylib strdup memory leak NSZombie not working - objective-c

Please help me track down an iOS memory leak. Thanks!
I'm using xCode 4.0.1 and I tried to activate NSZombie to track a memory leak, but it doesn't seems to work as before, with xCode 3.x
I can't find out where the memory leak is coming from, as Instruments points this out:
Leaked Object -> GeneralBlock-32
Address -> 0x4c8600
Size -> 32 Bytes
Responsible Library -> libsystem_c.dylib
Responsible Frame/Caller -> strup
At this point I don't know If I'm using Instruments with NSZombie the right way with xCode 4, as it doesn't show the NSZombie option when I click "i" for more information, under the left option Leaks.
OBSERVATION: My iPhone application plays a live stream mms/wma and also wma áudio files with a finite amount of time. The leak happens only with a finite wma file, but runs perfectly when I'm playing from a streamed source, with no ending time.

First, that is a malloc block, not an object. Zombies won't work (and would never have worked in prior versions either).
How many times does that leak happen? Once? Don't worry about it. Once per stream? file a bug -- that isn't in your code from what you have posted so far (unless your code is calling strdup, which is certainly possible but atypical in most iOS apps that aren't making heavy use of third party libraries... are you?)
In any case, unless it is leaking 100s and 100s of 32 byte allocations across the runtime of your app, don't worry about it (but please do file a bug).
As Valkio said, you can grab the stack trace of the allocation from gdb (or from Instruments) directly.

You can see where it was allocated if you do this:
Go to Product -> Edit Scheme -> Run
(Debug) -> Arguments.
Add this to environment variables: MallocStackLoggingNoCompact
Set it to YES
Run, and let it crash.
type in console (gdb) info malloc 0x4c8600 or whatever the address is.

Related

Malloc error incorrect checksum for freed object

I have written a objective-c wifi library and a c wrapper around it to call from my c++ code using corewlan framework.I have setup timers and on expiry of the timer i call scanwifi function of the library which gives details of all the wifi network details.The program keeps crashing by giving malloc error incorrect check sum for freed object. The crash is not consistent,keeps appearing a random places. I tried guard malloc to find the memory bug, left the program running for more than 10 hours but it didn't crash. as soon as i removed guard malloc and executed the program and boom there was the crash. Can anyone please tell ways to catch this memory bug
Thanks
Memory management errors can be particularly difficult to track down; without seeing code it's hard to say.
You mentioned GuardMalloc—have you tried enabling other Diagnostics?
Scribble
Guard Edges
Guard Malloc
Zombie Objects
This can help debugging by making your code crash more predictably—hopefully closer to the source of the error.
(In Xcode 4.4.1, these are set via "Product"->"Edit scheme"->"Run"->"Diagnostics".)

Finding all references to an object instance in Obj-C

I'm trying to track down some bugs, and one of them is related to a memory leak. It's an object that I can tell that something still has a reference to, since Instruments still shows it as being alive, but Instruments does not register it as a leak.
Is there anyway to look at an instance of an object in Objective-C and see what other objects still have a reference to that object?
I would recommend using the Allocations/ObjectAllocations Instruments template and then in the top right corner type the class name of your object (in the Category field).
You can then see the allocations increasing as you suggest and by viewing the extended detail you can see where they were allocated.
All content below this point was added by the OP (joshbuhler)
In the screenshot below, change the filter to "Objects List", and then by clicking on the little arrow to the right of the object's address, the history of memory events (alloc/retain/release/dealloc) will be show for that object. It won't show you exactly what is hanging onto that object, but it will give you some very useful info for tracking it down.
Cautionary Tail: :)
In the process of searching for a memory leak, I set a breakpoint (really a logpoint) in Xcode that would log the value of self when it was triggered troublesome logpoint image. Meanwhile I found the leak and patched it, but the memory usage wasn't leveling out, and my de-init was never getting called. The logpoint I set earlier was actually causing the retain count of my object to increase, and in turn that prevented de-init from ever getting called. I happened to discover this after several hours of wild goose chases which culminated in me stepping through my object's methods line by line, issuing p CFGetRetainCount(self) from debug console. When I stepped over the line with the logpoint, the retain count went up. At first I assumed it was some strange side effect of my code. I moved that logpoint so that I could set a normal breakpoint on that line, and my problem moved with it. I disabled the logpoint and the leak was gone. Hopefully this can help someone else.
If you're using xCode you can use the Performance tools to find the memory leaks. That will give you a nice graph of ALL memory allocation and if they are released or leaked.
xcode -> run -> Start with Performance Tools -> Leaks.
Memory leak detection tools

How can I track down a segmentation fault in a Cocoa application?

I'm having a problem with a Cocoa application I am writing. It has to parse a timestamped file that is updated every hour, and during testing it keeps crashing consistently at around 11:45 PM due to a segmentation fault. I'm assuming I must be messaging an object that has been deallocated. What tools are provided with the Xcode install to track object allocations and (hopefully) tell me if I am messaging an object that has been deallocated?
I am using Mac OS X 10.5.
I would recommend the following:
Use NSZombieEnabled to monitor when messages are sent to deallocated NSObjects
Use Instruments to track object allocations and/or memory leaks
The way I do it is by using a command line tool called gdb. Here is a tutorial on how to use it. You'll have to learn a few of it's commands, but once you do it's almost a pleasure to use.
Note: gbd can be used on C, C++, and Objective-C programs.
Have you run the program under gdb? This should allow you to inspect the stack and variables when it SIGSEGVs.
To track allocations, use malloc_history. This requires the MallocStackLogging environment variable to be set.
A quick point: using a deallocated memory location usually results in a EXC_BAD_ACCESS exception. If that's the crash reason you're seeing then you're correct in assuming it's a deallocation problem.
Run it in Xcode's debugger (which is gdb with a GUI on top) and reproduce the crash. Then, look at the stack trace.
Messaging a deallocated object usually has the top frame in objc_msgSend. The next step then is to run the app with NSZombieEnabled and reproduce the crash; the zombie will identify itself.

App crashes without Garbage Collection enabled

As the title says, my app crashes when garbage collection is not enabled. The app pops up for a few seconds and then it just crashes, with nothing but this in the debugger console:
[Session started at 2009-08-17 15:03:20 -0600.]
GNU gdb 6.3.50-20050815 (Apple version gdb-966) (Tue Mar 10 02:43:13 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".sharedlibrary apply-load-rules all
Attaching to process 12535.
unable to read unknown load command 0x22
unable to read unknown load command 0x22
unable to read unknown load command 0x22
unable to read unknown load command 0x22
I don't know why its happening. I think its probably a memory management issue. I used AnalysisTool (front-end to Clang Static Analyzer) to check for leaks and memory management issues, and I fixed the issues it found. Running the app through Instruments however reveals a memory leak around the time it starts. I have no idea where this leak is coming from...With garbage collection enabled the app runs fine, but Instruments still finds a leak.
Source code is available upon request
Thanks
Since the error says it occurs when calling [CFArray countByEnumeratingWithState:objects:count:] on a deallocated object, that gives you a fairly good idea of where to look. That method is part of part of NSFastEnumeration, so unless you're calling that method directly (highly unlikely), it is being invoked from within a for (... in ...) loop on your array object. If you can figure out where that is, you can set a breakpoint on (or just before) the for loop and check whether your object has been deallocated. The most likely cause of the problem is failing to properly retain the array, and it is probably released by the run loop draining an NSAutoReleasePool.
XCode has a bunch of memory profiling support built in - turning those on might reveal more information. I found these links particularly helpful:
http://developer.apple.com/technotes/tn2004/tn2124.html#SECMALLOC
http://www.cocoadev.com/index.pl?NSZombieEnabled
http://www.cocoadev.com/index.pl?DebuggingTechniques
http://www.cocoadev.com/index.pl?DebuggingAutorelease
You're probably releasing an object when you shouldn't, then sending it a subsequent message. unfortunately, the crash (where the subsequent message is sent) isn't where the problem is - it's where you are releasing (or worse, deallocing) where you shouldn't. The clang static analyser isn't foolproof, and blindingly following the advice won't necessarily have helped.
If it crashes after showing something for a few seconds, it may indicate that something that needed to be retained was released by the autorelease pool at the end of the run loop. Have a look at places where you assign variables with objects returned by other methods. Any method without "new", "copy", "alloc" (there's a few others I think) in the name usually indicates that you'll need to retain it if you want to keep using it.
It could also mean that you have released something that you shouldn't have and it was released again by the autorelease pool. Have a look at all the places you are releasing objects and make sure that you are only releasing objects that you have either retained yourself, or releasing objects returned by methods that explicitly state ownership, such as "new", "alloc", "copy", "mutableCopy" and so on.

Avoiding, finding and removing memory leaks in Cocoa

Memory (and resource) leaks happen. How do you make sure they don't?
What tips & techniques would you suggest to help avoid creating memory leaks in first place?
Once you have an application that is leaking how do you track down the source of leaks?
(Oh and please avoid the "just use GC" answer. Until the iPhone supports GC this isn't a valid answer, and even then - it is possible to leak resources and memory on GC)
In XCode 4.5, use the built in Static Analyzer.
In versions of XCode prior to 3.3, you might have to download the static analyzer. These links show you how:
Use the LLVM/Clang Static Analyzer
To avoid creating memory leaks in the first place, use the Clang Static Analyzer to -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:
Download the latest version from this page.
From the command-line, cd to your project directory.
Execute scan-build -k -V xcodebuild.
(There are some additional constraints etc., in particular you should analyze a project in its "Debug" configuration -- see http://clang.llvm.org/StaticAnalysisUsage.html for details -- the but that's more-or-less what it boils down to.)
The analyser then produces a set of web pages for you that shows likely memory management and other basic problems that the compiler is unable to detect.
If your project does not target Mac OS X desktop, there are a couple of other details:
Set the Base SDK for All Configurations to an SDK that uses the Mac OS X desktop frameworks...
Set the Command Line Build to use the Debug configuration.
(This is largely the same answer as to this question.)
Don't overthink memory management
For some reason, many developers (especially early on) make memory management more difficult for themselves than it ever need be, frequently by overthinking the problem or imagining it to be more complicated than it is.
The fundamental rules are very simple. You should concentrate just on following those. Don't worry about what other objects might do, or what the retain count is of your object. Trust that everyone else is abiding by the same contract and it will all Just Work.
In particular, I'll reiterate the point about not worrying about the retain count of your objects. The retain count itself may be misleading for various reasons. If you find yourself logging the retain count of an object, you're almost certainly heading down the wrong path. Step back and ask yourself, are you following the fundamental rules?
Always use accessor methods; declare accessors using properties
You make life much simpler for yourself if you always use accessor methods to assign values to instance variables (except in init* and dealloc methods). Apart from ensuring that any side-effects (such as KVO change notifications) are properly triggered, it makes it much less likely that you'll suffer a copy-and-paste or some other logic error than if you sprinkle your code with retains and releases.
When declaring accessors, you should always use the Objective-C 2 properties feature. The property declarations make the memory management semantics of the accessors explicit. They also provide an easy way for you to cross-check with your dealloc method to make sure that you have released all the properties you declared as retain or copy.
The Instruments Leaks tool is pretty good at finding a certain class of memory leak. Just use "Start with Performance Tool" / "Leaks" menu item to automatically run your application through this tool. Works for Mac OS X and iPhone (simulator or device).
The Leaks tool helps you find sources of leaks, but doesn't help so much tracking down the where the leaked memory is being retained.
Follow the rules for retaining and releasing (or use Garbage Collection). They're summarized here.
Use Instruments to track down leaks. You can run an application under Instruments by using Build > Start With Performance Tool in Xcode.
I remember using a tool by Omni a while back when I was trying to track down some memory leaks that would show all retain/release/autorelease calls on an object. I think it showed stack traces for the allocation as well as all retains and releases on the object.
http://www.omnigroup.com/developer/omniobjectmeter/
First of all, it's vitally important that your use of [ ] and { } brackets and braces match the universal standard. OK, just kiddin'.
When looking at leaks, you can assume that the leak is due to a problem in your code but that's not 100% of the fault. In some cases, there may be something happening in Apple's (gasp!) code that is at fault. And it may be something that's hard to find, because it doesn't show up as cocoa objects being allocated. I've reported leak bugs to Apple in the past.
Leaks are sometimes hard to find because the clues you find (e.g. hundreds of strings leaked) may happen not because those objects directly responsible for the strings are leaking, but because something is leaking that object. Often you have to dig through the leaves and branches of a leaking 'tree' in order to find the 'root' of the problem.
Prevention: One of my main rules is to really, really, really avoid ever allocating an object without just autoreleasing it right there on the spot. Anywhere that you alloc/init an object and then release it later on down in the block of code is an opportunity for you to make a mistake. Either you forget to release it, or you throw an exception so that the release never gets called, or you put a 'return' statement for early exit somewhere in the method (something I try to avoid also).
You can build the beta port of Valgrind from here: http://www.sealiesoftware.com/valgrind/
It's far more useful than any static analysis, but doesn't have any special Cocoa support yet that I know of.
Obviously you need to understand the basic memory management concepts to begin with. But in terms of chasing down leaks, I highly recommend reading this tutorial on using the Leaks mode in Instruments.