XCode 4.2: Tracking Down Deallocated NSString - objective-c

I am trying to track down where an NSString is getting deallocated. I have enabled GuardMalloc, NSZombie, and Log Malloc Stack for my application (as described here). When I run info malloc-history 0x29d39fe0 in the console, I get the following error:
warning: MallocStackLoggingNoCompact not set in target's environment so the malloc history will not be available.
This is leading me to believe the error is with one of my library projects. How could I enable the above for library projects?

Thanks to Adam for the lead (in the comments above). I was able to use instruments to track down where the extra release was occurring (which happened on an autoreleased object).
I followed the instructions here. Making sure the extended view was open, I was able to determine the exact line of code that had the offending release call.

Related

ERROR objc_retainedObject() unavailable

when i'm trying to build my project I have a new error where objc_retainedObject() is used.
I have the error message objc_retianedObject is unavailable: use CFBridgingRelease() or a (__bridge_transfer id) cast instead.
I replaced the usages of objc_retainedObject() by CFBridgingRelease and there are no longer errors and I can run the app, but when the app is going to display my QRCode-scanning view, it crashed without messages.
It is the same when I put #define objc_retainedObject(o) ((__bridge_transfer id)(objc_objectptr_t)(o)) which was supposed to be a solution.
I believe that it is an XCode configuration or a missing library problem. Any ideas?
Do not recreate objc_retainedObject. It was removed on purpose. CFBridgingRelease and CFBridgingRetain are the correct tools for moving CF objects into ARC. (__bridge is the tool for dealing with CF objects that you don't need to transfer to ARC because you aren't storing them.)
If your program is crashing, you're probably managing memory incorrectly. It is likely that objc_retainedObject was incorrect (even if you happened to get away with it). See when should you use __bridge vs. CFBridgingRelease/CFBridgingRetain? for correct memory management when transferring CF objects to ARC.
Without knowing more about the code, I can't guess exactly where you've made a mistake, but you probably are calling CFBridgingRelease on an object that you didn't acquire via the Create Rule. You don't just throw CFBridgingRelease on every CF object you encounter. You need to make sure you're balancing an existing retain.

autorelease not allowing to compile code

I am trying to convert an old code to an ARC code.
However, i am getting a build error at the following line
[[token retain] autorelease];
I get 3 errors in the following order:
-'autorelease' is unavailable: not available in automatic reference counting mode
-[rewriter] it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately
-ARC forbids explicit message send of 'autorelease'
If i remove this particular line, then the code compiles correctly
If that is all that is on the line, you can probably just remove it. That code claims a reference to the object but also says you don't want to worry about releasing later, but with ARC you don't have to worry about it.
I am guessing that Xcode did not get rid of it automatically because of lack of context. If it had been in a more common location, such as in a return statement, it would be obvious what the intent was. When it is all by itself, it could be, but probably is not, something more complicated.
ARC manages your memory for you, so you don't need to call "autorelease", "release", "retain" etc. With ARC the compiler retain and release objects as necessary for you so you don't have to explicitly make these calls. If you want to manually manage your memory disable ARC, or you can use the compiler flag "-fno-objc-arc" to disable ARC on a specific class.
ARC means you don't have to use release, retain or those other pesky memory management things. ARC add them all for you automatically when you compile the app. Read more here
If you have old code where it would not be the best solution to remove all the memory management calls, then check this answer to disable ARC for particular files

What are ARC restrictions, and how can I remove them?

I just downloaded an Xcode project, and I get all these errors about "ARC Restrictions." What are these, and how can I remove them?
There are basically two versions of memory management in objective-c. ARC and... well, "Not ARC" :-) You probably downloaded a project, which doesn't use ARC already. Simplest way of resolving your problem is to instruct the compiler to treat your sources as "Not ARC". Explained here.
And here is a good tutorial that should get you started with ARC.
ARC automatically keep track of memory release and retain so you can not release and retain any memory manually.
ARC also doesn't allow any method to be get called at compile time which prototype is not declared in interfaces.
It has also introduced new #autoreleasepool block. so it doesn't not allow older autorelease of an object automatically
However it has allowed dealloc method to be written, but it doesn't allowed [super dealloc] to be get called.
There are much more written about ARC at this blog you can checkt it here
You can covert your project to ARC using xcode in following way.
Go to Edit -> Refactor -> Convert to objective c arc.
However it has some compatibility issue with git repository so it does not convert when .git folders are there in projects. so you will have to remove it first and then convert it. check this link

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.