how to debug EXC_BAD_ACCESS on iPhone

October 31, 2009

EXC_BAD_ACCESS. Debugging this one is on par with figuring out why the wife says “not tonight, honey.” And they are equally unfortunate situations.

Let’s see what we can do about EXC_BAD_ACCESS.

EXC_BAD_ACCESS happens when a message is sent to an object that has already been released. By the time the error is caught, the call stack is usually gone especially if dealing with multiple threads.

How nice would it be to keep a dummy around after the object is released that could stop execution, tell us what message was sent and show us the call stack… well, there’s a way to do just that.

If you set the NSZombieEnabled environment variable, the Objective C runtime will leave a dummy object behind for every deallocated object. When the zombie object is called, execution stops and you can see the message that was sent to the object and the call stack that tells you where the message came from (it doesn’t tell you where you over released the object, but knowing where the object is called from should get you pretty close to the problem.)

To set this variable, go to the info panel of the executable in xcode, and create a new environment variable in the arguments tab by clicking the plus sign in the lower left corner of the window. Name the variable NSZombieEnabled, type YES for the value and make sure that the checkbox is selected.

set NSZombieEnabled variable

set NSZombieEnabled variable

Go ahead and run your program now (in debug mode, because you need the stack information.) When the over released object is accessed, you get an error message similar to this (xcode debug view):

2009-03-30 02:30:36.172 ninjaJumper[3997:20b] *** -[GameLayer retain]: message sent
to deallocated instance 0x59bf670

This shows the class of the object (GameLayer) and the message sent (retain).

Let’s take a look at the stack now:

call stack

call stack

The methods printed in bold are in your code, the others are in some other API. Here you can see that the object was accessed from [Director touchesBegan:withEvent], where an array was copied (most likely the over released object was in the array.)

This information should get you pretty close to the problem.

Once the problem is fixed, make sure that the NSZombieEnabled variable is disabled. You don’t need to delete it, but make sure that the checkbox is unchecked:

NSZombie disabled

NSZombie disabled

Now about the wife. Good luck there. Try a box of chocolate or load the dishwasher for a couple days.

122 Responses to “how to debug EXC_BAD_ACCESS on iPhone”

  1. This sounds great! Unfortunately, no more info came through for me… same cryptic EXC_BAD_ACCESS… nothing more. I did set the NSZombieEnabled:YES in the arguments page for the executable… Checkmark too…

  2. Are you running your app in debug mode? What API are you using when you get EXC_BAD_ACCESS?

  3. Hey - thanks for posting…

    Yes, running in debug. 2.2.1 iPhone.

    I later got the results you describe while debugging something else… The one I was working on must be goofy enough to not give these results…

    As a matter of fact, it makes sense (I think) as it turned out to be an issue with passing the pointer to an error (which I wasn’t doing) and thus the object never existed to be “persisted” as a dummy…

    Loose Screw Behind Keyboard (again!) I’m afraid ;)

  4. You rock.

  5. As payment for this stellar, time-saving post, I purchased your Ninja game. I’m already a Ninja, so I should be able to score really high.

  6. Man, you saved me a TON of time. What an awesome tip.

  7. Thanks a lot man, this is a great tip!

  8. Incredible tip! Now if I could only find out why the UITableViewController is being deallocated!

  9. @Mike: Make sure that you are either:
    - retaining it or
    - assigning it to a retaining property

  10. @lajos

    Thanks. I am now retaining it. :-)

  11. You saved my day!!!

  12. Thanks! This just saved my night!

  13. Great post, saved me tons of time!

  14. 2 thumbs up!

  15. This just saved me a LOT of time and confusion. Thank you!

  16. Thank you…

    I spent two days after work , my family was starting to miss me. Finally used your recommendation to find the error, in less than 10 minutes it was fixed.

  17. Awesome, thanks. Now is there any way that “ninjaJumper[3997:20b]” can be displayed in a more useful manner such as “ninjaView.m:line 6 - viewdidLoad”?

  18. Help me, please …

    I spent two weeks with this and I have no idea what could be the problem :(

    EXC_BAD_ACCESS

    *** -[Not A Type release]: message sent to deallocated instance 0×19c0e0

    (sorry for my english)

  19. I have finally found it :)

    CGImageRelease(maskRef);

    Thank for this tip - I would never solve this without it.

  20. THANKS!

  21. This has really, really helped. Thanks for going the extra mile and providing screenshots (esp. for the environment variables). I’ve enabled NSZombieEnabled with my wife and her errors are now much more explicit.

  22. [...] » how to debug EXC_BAD_ACCESS on iPhone codza » how to debug EXC_BAD_ACCESS on iPhone To set this variable, go to the info panel of the executable in xcode, and create a new environment [...]

  23. Nice. After I filled the dish washer a few days, my wife said that I can also clean the windows now, and for birthday she gave me an iron and cleanung gloves wih my name engraved.

  24. Very handy tip! You’ve saved me a lot of time. Now what sucks is my call stack is in the autorelease pool, so I’m starting to suspect a framework I use.

    NSZombieEnabled Works for Mac OS X too, I hear.

  25. How this saved my life. Thank you so much.

  26. Absolute life saver. 6 hours of scouring my first real project that wasn’t running at all until that point and no joy. All other guides I found just re-iterated the same ol rules which is no use when you’re not even sure which file the error is in.

    Obj-c is the scourge of the devil when it comes to memory management and is about as annoying as AOL.

    I come from java & c experience and this is just so much pain compared to both of them, I don’t care what the mac evangelists say.

    Everyone should use java. Most errors are caught at compile time, and the runtime ones point you straight to the problem with a stack trace that is actually useful and doesn’t assume you want to look at assembler code straight away (why does Xcode do that?).

    Anyway, fantastic tip, solved prob this way in <10 mins.

  27. Very useful tip !!

  28. this tip has allowed me to pinpoint my errors very quickly - thanks!

  29. Absolutely PRICELESS. I’ve read millions of threads for so many different things over time and I have never left a comment. Your post warrants eternal thanks.

  30. Thanks for ur post, I must watch what I’m doing with my object management in future. Ha ha.

    Programmer for years, Objective C noob.

  31. thx! very good!

  32. Excellent tip, Lajos. Kind of you to share it with us.

  33. Thanks a lot … it’s really helpful

  34. Hey, could anybody tell me how to see the stack trace. I am unable to find it.

  35. @krazydeveloper: open the debugger (shit+command+y). The call stack is the window in the upper left, you can step back (down?) to find where you are crashing.

  36. @lajos: I got it. Thanks a lot.

  37. thanks! very helpful.

  38. Thanks for the info. Very useful! I actually applied this to Mac OS X and it still works as advertised.

  39. Thanks a lot for the guide. But I still have questions for this.

    I do not know why I could not catch my EXC_BAD_ACCESS, I assumed it working on Device Debug build.

    I got a very strange error in Debug build on device, but no issue for release version. It broke inside a SQL call, sqlite3_prepare_v2->sqlit3_declare_vtab->sqlite3_blob_write.

    If someone can give me some clue I appreciate much!

  40. What if the error is only happening on Device. Say for instance you have:

    #if TARGET_IPHONE_SIMULATOR
    //Simulator calls that cant use PrivateFrameworks in SDK
    #else
    //Private Framework stuff
    #endif

    How would you NSZombie this? Or figure out what KERN_INVALID_ADDRESS at 0×6c707069 pertains to??

  41. @Aaron: NSZombieEnabled keeps deallocated objects around so it’s for debugging overreleased objects. I don’t think you can use it to debug invalid calls into the API.

  42. I am trying to use your tip. It seems that it will help me just as it has helped all these others. But, I don’t know how to “look at the stack now” I do see an over-released variable (I think). It says “-[NSPathStore2 release]: message sent to deallocated instance 0×1441a0.” I have no idea what class that is (I have no such class in my app). And I don’t know how to find that address on the stack since I don’t know how to look at the stack.

    Thanks!

  43. Thank you very much, this made my day! =))

  44. Maybe you create some other object that allocated an instance of NSPathStore2 as its member.

    /quoted ————————/
    Sam Rhoads
    December 18th, 2009 at 5:40 pm
    I am trying to use your tip. It seems that it will help me just as it has helped all these others. But, I don’t know how to “look at the stack now” I do see an over-released variable (I think). It says “-[NSPathStore2 release]: message sent to deallocated instance 0×1441a0.” I have no idea what class that is (I have no such class in my app). And I don’t know how to find that address on the stack since I don’t know how to look at the stack.

    Thanks!

  45. YOU ARE AMAZING. You just saved me hours on a really important project for school. Like, you helped me graduate. YOU ARE THE BEST. Thank you again, and Happy New Year!

  46. Wanted to echo all the other comments and say thanks. Honestly, I was lost with a crash when popping a view controller from the UINavigation controller, which I eventually traced back to an array in my delegate which I’d declared autoRelease when I shouldn’t have. I don’t think I ever would have found it without this.

  47. Thank you very much. This helps a lot.

  48. Great advice about the error. I do remember hearing an adopted grandmother say once, “The sexiest thing she ever saw was her husband doing the dishes”. He said that really worked for him…. into his 80’s.

    Oh and the NSZombiEnabled too.

  49. Thanks a lot! Saved me some hours ;]

  50. I wish I knew this 6 months ago. Thanks for sharing.

  51. Excellent tip! Saved me hours of time tracking down an obscure failure. Thanks!

  52. Thank you! Project so finished I tried to do away with some perceived memory leaks … your tip told me I released a UIArray too much too soon. Now I don’t and it runs smoothly again. I can live with those memory leaks (don’t even remember them!)…

  53. Hi there,
    first of all thanks for your tip.
    I have a question:
    - I set the NSZombieEnabled variable to YES
    - I run my app in debug mode
    - I get from the Debugger Console the “old” message:
    Current language: auto; currently objective-c
    Program received signal: “EXC_BAD_ACCESS”.
    with “xcode debug view” you call the debugger console?
    Where is my error???
    I use Xcode 3.2.1 on Mac OSX Snow Leopard.

    Thanks

  54. @oscar.peli: EXC_BAD_ACCESS means that you are trying to access memory that’s already been freed. It can happen either when you’re overreleasing an object (in which case NSZombieEnabled will tell you the name of the object) or you have a c pointer that’s accessing already freed memory with free(). If you’re sure that you set up NSZombieEnabled correctly and don’t get any information in the debugger console, check the call stack and see if you have issues with malloc/free.

  55. thanks for your answer.
    I suppose that the cause of my error is far away from the point it shows.
    I’m using Core Data and I send child entities to child ViewControllers.
    I use the following code:
    myViewController *myVC = [[myViewController alloc] initWithNibName:@”myNib” bundle:nil];
    myVC.entity = [self entity];
    myVC.managedObjectContext = self.managedObjectContext;
    [self.navigationController pushViewController:myVC animated:YES];
    [myVC release];

    Do you think that the last release cause a memory leak???
    Thanks

  56. @oscar.peli: the navigation controller retains your view controller, so that release is is needed (it would leak if you didn’t release).

  57. i don’t know how you figured this trick out - but damn. thanks a lot for sharing.

  58. Codza… I love you :-) You’ve just saved me thousands of debugging hours in the years to come. Thanks pal.

  59. Great!!

  60. Your tip just helped me fix a bug that had been plaguing me for a few days. Thanks!

  61. Thanks man it ” Solved “;

  62. In my case variable NSZombiEnabled not helped. :( In debugger console I can watch “Program received signal: “EXC_BAD_ACCESS”” message. That is all!

    The CorePlot project is attached to my project. If error happened in CorePlot source is it possible no message about deallocated object?

  63. @Shuriken: NSZombieEnabled only helps with bugs related to accessing released obj-c objects. If the issue is with c pointers accessing freed or unallocated memory, it won’t help. In that case you could check the call stack to get some info about yhe bug.

  64. Stack trace doesn’t get anything:

    #0 0×32916228 in x_heap_free
    #1 0×32915f34 in CALayerLayoutIfNeeded
    #2 0×32915844 in CA::Context::commit_transaction
    #3 0×32915474 in CA::Transaction::commit
    #4 0×3291d5dc in CA::Transaction::observer_callback
    #5 0×31432830 in __CFRunLoopDoObservers
    #6 0×3147a346 in CFRunLoopRunSpecific
    #7 0×31479c1e in CFRunLoopRunInMode
    #8 0×325323a8 in GSEventRunModal
    #9 0×3314ec30 in -[UIApplication _run]
    #10 0×3314d230 in UIApplicationMain
    #11 0×00003090 in main at main.m:14

  65. Thanks for tip. I had learned the same thing in class a few days ago but this was a good reminder. I was able to eventually figure out what was wrong but thread window didn’t give me the method and line name I was looking for. This may be due because my app is multithreaded.

  66. Dude, you just saved my weekend! I was sitting here dropping breakpoints all over my code trying to narrow in on that error.

    Just in case this helps anyone:

    I created an array in the header file with properties and everything but never used it correctly during the code. So it was being released without ever being properly used. Code works stellar now! thanks man!

  67. You just saved my day, thanks for the great info!

  68. [...] March 18, 2010 by dw2bin While writing a simple iPhone application today, I ran into a horrible “EXC_BAD_ACCESS” error. This happens when a message is sent to an object that has been released, and as it turns out, this error is extremely difficult to trace since there is no call stack available or any other useful info (there is an excellent explanation of this error and how to debug it here: how to debug EXC_BAD_ACCESS on iPhone). [...]

  69. you mis-spelled the variable name as ‘NSZombiEnabled’ in the article (instead of NSZombieEnabled).

  70. @xastor: thanks! fixed…

  71. Thanks! Worked for me! This tip is very important for a naive iPhone developer

  72. Nice Nice! This is just what i need.

  73. Hi all. I’m glad to see a thread discussing a problem that is similar to the one I’m facing. I would really appreciate it if you could provide me with your feedback.

    I have built the following:

    1. One controller with a xib that provides users with the ability to enter some data and I would provide them with feedback
    2. Another Audio controller (RMAudioCtrl) that exposes two IBAction’s to Record and Play. I created this as a separate controller for modularity.
    3. On the xib for the first controller, I added a UIViewController and changed its type to RMAudioCtrl and connected two buttons on the xib to its record and play actions.

    When I click on one of these buttons, the program halts with a ___forwarding___ error and I don’t seem to be able to do anything after that. If I take out the connections to the IBActions then things are ok (well, nothing happens when I click the buttons).. but one thing to note is that I get the following in the console:

    2010-04-03 16:47:17.572 RescueMe[4472:207] *** -[RMAudioCtrl performSelector:withObject:withObject:]: message sent to deallocated instance 0×13c510

    Any help would be appreciated.

    al

  74. @al: Is RMAudioCtrl visible when you send the message? If it’s not visible, it’s probably already released. You can retain it in your other view controller. However it’s hard to know what’s going on without seeing the code. If you can’t figure it out, feel free to contact me.

  75. Hi Lajos,

    Thanks for responding. I don’t know if this makes much sense but I don’t have an interface for RMAudioCtrl. I just created its .h and .m files to contain all what is required to record and play then from xib of my main interface (which is controlled by another controller), I added a UIViewController to its Document Window then changed that new controller’s type to RMAudioCtrl. Then I added two buttons to the xib and linked them to the record: and play: methods in RMAudioCtrl..
    I would love to share the code with you but I’m doing this for a company and I would need to get their approval to share it.. I’m a bit of a novice user so I hope I’m making sense and appreciate your help.

  76. @Alan:

    If you have both view controllers in the same xib, you can hook up iboutlets from one to the other. If they are in separate xibs, you have to do it from code.

  77. Hi Lajos,

    Can you please send me your contact info? I have taken a screenshot that I can e-mail to you.

    Thanks,

    al

  78. Thank you! Thank you! Thank you!

    I already knew *where* the problem was but from your tips found out that a certain object needed needed to be superglued in place.

  79. [...] http://www.codza.com/how-to-debug-exc_bad_access-on-iphone Some hints and tips with debugging apps [...]

  80. Thanks dude!

  81. Dude you would have saved the day if I was accessing an Objective-C object! I bookmarked this so it could one day save the day =)

  82. Great! helps me alot!

  83. Hi. I’m doing a tab bar navigation controller app. The first view is a table listing of all of the podcasts on the device, followed by a listing of episodes once the user selects a podcast. I use MPMediaQuery to populate the table view. I get what looks like an applicable error in the console (that can be used with this debugging technique):

    2010-05-07 15:18:00.996 auditorium[6070:207] *** -[CFArray release]: message sent to deallocated instance 0×14d900
    (gdb)

    But when I go to look at the stack trace, it has nothing in bold.

    #0 0×3352490c in ___forwarding___
    #1 0×3351bac0 in __forwarding_prep_0___
    #2 0×330829f6 in -[MPMediaQuery dealloc]
    #3 0×33542f36 in -[NSObject release]
    #4 0×30ace11a in NSPopAutoreleasePool
    #5 0×30ad2770 in -[NSAutoreleasePool release]
    #6 0×325d25f2 in _UIApplicationHandleEvent
    #7 0×302499ec in PurpleEventCallback
    #8 0×33560c2c in CFRunLoopRunSpecific
    #9 0×3356035c in CFRunLoopRunInMode
    #10 0×3259774e in -[UIApplication _run]
    #11 0×32596472 in UIApplicationMain
    #12 0×00002bd8 in main at main.m:14

    Any suggestions?

  84. The first view successfully lists all of the podcasts, but nothing in the list is selectable.

  85. Awesome! I’ve spent several hours on spying EXC_BAD_ACCESS bug in my app. Now it’s gone in 10 minutes. Thanks :)

  86. Super AWESOME!!!

  87. So I must be the only one here that has enabled everything suggested in this blog and I still receive exactly the same thing..
    Program received signal: “EXC_BAD_ACCESS”.
    :(

    I even tried using Instruments with tracking NSZombies and that didn’t work either. How could this be? Xcode 3.2.1. Cheers guys.

  88. Thanks a LOT! Objective-C is easier than ever because of you!!!!!

  89. @Graham: NSZombies only work on obj-c objects. Most likely you are accessing a c pointer pointing to memory already freed.

  90. [...] 詳細的原文在這:Link [...]

  91. Thanks, you helped me find my bug tonight.

  92. Really awesome.

    i can’t do anything with the message EXC_BAD_ACCESS but after enabling the zombie-mode i could figure out the problem and solve it.

    regards

  93. Thanks for the tip. Helped me debug my error immediately :)

  94. Hello,

    With all of the great comments, I thought this would help me. I get the same error that this references, have built with NSZombieEnabled=YES, but I hit the error during a run and there is no stack data in the debugger, it’s just dead. The only time I can see variables is when I hit a breakpoint.

    Does any of this sound off, is there a step I might be missing?

    Thanks!

    Rob

  95. @Rob: If you have the NSZombieEnabled argument set up correctly and your app is still crashing without any debug info, most likely the crash is due to accessing freed or unallocated memory using a C pointer. Look at the crash logs on the device, hopefully you’ll find some info there.

  96. Thanks !

  97. The variable isn’t giving me any extra info either. I do know that the EXC_BAD_ACCESS is being thrown through execution of this line:
    NSString *url = [[NSString alloc] initWithFormat:@”1.2.3.4/blah/controller/action?user=%@&pass=%@”,un,pas];
    where un and pas are arguments. The strange thing is that it worked without a hitch until I switched to an IP instead of a URL (so that I could test on my dev machine without having to deploy every time).

  98. Lajos, thanks A LOT man. Your tip has saved me hours of solving my obj-c code problem.

  99. This TOTALLY saved my life. Thanks a BUNCH!!!

  100. This really helped me out! Thanks for the tip!

  101. You saved my time. Thanks for g8 tip!

  102. You Rock!!! I hate when I get these obscure errors. This helped point in the right the direction of many errors within my code. I can imagine using this again and again.

  103. One more thank you on the pile! I’ve just spent 4 hours not realizing that I didn’t remove an observer when I dealloc’ed the class.

    THANK YOU!!!!! ;-)

  104. Oh my god! Thank you so much!

  105. And Bookmark! Thanks to you I found the problem in minutes instead of years!

  106. Really nice!

  107. Thanks for the post.

    It didn’t help me with the issue that led me to this post but it helped with another.

    For those that asked - ‘where’ to enable/add in 3.2 (and maybe 4.0):
    On the left side of your xcode screen: Groups & Files
    Click the arrow next to Exacutables, then click your app name under Exacutables so it is highlighted. Click the big blue/white (i) [icon] top-center of xcode.

    I had a working target-iPad uiviewcontroller to download file(s). Had a [Done] button to close the view (sent [connection cancel] if download was active], using a textview for a status box, couple of labels for current file name etc.

    To make it pretty I added a UIProgressView (progress bar). Without even connecting the outlet - ERR_BAD_ACCESS on [self dismiss...] - but only sometimes.

    When I enabled NSZombieEnabled - never crashed. Worked everytime with no messages in console or debugger - never crashed.

    Uncheck NSZombieEnabled - crash *sometimes*.

    After sleeping on it (sometimes staring at code and fighting with it is just a waste) - I fired up xcode, when to my view controller and moved:
    [super dealloc];
    from the top of - (void)dealloc { to the bottom

    What it was (that crashed random):
    - (void)dealloc {
    [super dealloc];
    [doneBtn release]; //my button to close the view
    [prgBar release]; //my progress bar
    }

    Changed to (and now never crashes sim or device):

    - (void)dealloc {
    [doneBtn release]; //my button to close the view
    [prgBar release]; //my progress bar
    [super dealloc];
    }

    Hope the info helps.

  108. Oh ~ You are Greate Man, Thank you Thank You * 10000

  109. Thanks for this helpful tip! Just a note, I had to restart xcode before it worked for me.

  110. Yep. It was a good one. Helped a lot. Thank you. Seeing that EXC_BAD_ACCESS for the first time sucked.

  111. ok so im getting back
    -[__NSArrayM release]: message sent to deallocated instance 0×5d44440
    but have no idea what array its talking about.
    any ideas?

  112. Ahhh well funny story about my problem… i found out (yes im new to object programming) that when i called a method from another page (i.e. [anotherfile alloc] its in the autorelease pool. and I was just over thinking and looking the problem but after a few shoots with my friends and my thinking ability was knocked down I looked at the programming and was like hmmm u know im not actually alloc that on this page lol…another funny story for the books. thanks for your tips I would have never known where to look without them!

  113. but…. since NSZombieEnabled, my EXC_BAD_ACCESS does not appear???
    maybe I should rest for a while

  114. Dean Wiley, you save my wife.
    http://stackoverflow.com/questions/909856/why-do-i-have-to-call-super-dealloc-last-and-not-first also saves my life.
    Another rule of thumb learned, to call [super dealloc] at the end after releasing others.

  115. Thanks for the tip. It was extremely helpful.

    The following is a very good article on NSZombieEnabled:
    http://www.cocoadev.com/index.pl?NSZombieEnabled

    It is required reading if you are thinking of using NSZombieEnabled.

    One excerpt that helped me was:
    Use in Xcode:

    Double-click an executable in the Executables group of your Xcode project.
    Click the Arguments tab.
    In the “Variables to be set in the environment:” section, make a variable called “NSZombieEnabled” and set its value to “YES”.

    There is other important informatin there too, specifically DO NOT leave it set to yes on a release build.

  116. Dude, thanks so much. After a lot of head scratching I did this and it immediately stopped on the line in dealloc that was causing the issue. Done and done. Will buy an app or two of yours in return for the help. Thanks!

  117. Thanks for the tip! If I knew about this earlier it could have saved me hours of development time… Much appreciated!! :)

  118. [...] you try to do anything with it. The easiest and most reliable way to turn on NSZombies is detailed over here. Sure enough, a run with Zombies enabled gives me one of [...]

  119. Wow - bodaciously awesome tip. I wish I had thought to search for it before I spent an hour and a half trying to figure out what was getting released myself.

  120. Edit Executables not work for me…
    I can’t figure out EXC_BAD_ACCESS
    But it’s strange ,my app runs normal on iphone 3 but CRASH on touch4/iphone4
    my program is send a pic and GPS location to server
    here is the message I got :”Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.
    &
    Using two-stage rotation animation is not supported when rotating more than one view controller or view controllers not the window delegate”

    on iphone 3 I got “ERROR: FigCreateCGImageFromJPEG returned -12905. Input (null) was 638420 bytes.”(is this normal ?)

    hope some one can help me…Thanks for all reply

  121. @Codza,
    This help ha shelped me on a TOPN of occasions. On this one in particular, I was getting no message - until I read through the comments here.

    @Dean Wiley,
    Moving my [super dealloc] statement to the bottom of the dealloc method solved this for me. Thanks for the tip!!!

  122. You really deserve a 5 star congratulation !
    Thanks for the time you saved me !

Leave a Reply