so i have a program i am developing and as im fairly new to objective-c and cocoa touch im not very familiar with the concepts of memory management in ipad app development. my problem is that my program keeps crashing without any warning and without telling me why, i turned on breakpoints and it shows an exc_bad_access signal. which leads me to believe that im not handling the memory properly. or its something else that i've over looked in my efforts. either way i need some help. if anyone can take a look at the app and tell me anything that may be causing it to act the way it is that would be great.
the point of the program is that it shows 20 mayan glyphs of the numbers 0-19, you drag the glyphs one at a time into the white 'drop zones' and it adds them and displays the result. however almost every time as soon as the second glyph is dropped in it quits, or it will display the answer and when you remove one of the glyphs to add another set it will quit then.
any help would be greatly appreciated. thanks stackoverflow :)
source files here
why don't you read Apple's documentation, which is reasonably excellent on this particular topic?
http://developer.apple.com/iphone/library/documentation/cocoa/conceptual/memorymgmt/memorymgmt.html
Get to know the debugger. At the point at which you see the EXC_BAD_ACCESS and the program halts, look at the call stack to actually see what the source of the signal was.
Also, in the case of an issue with accessing an object that has already been deallocated, it's useful to have NSZombieEnabled set to YES in your environment variables. To do that open the info panel for your executable (Groups & Files pane, expand 'Executables', and open the info panel for the executable your project builds) and in the "Arguments" add an environment variable named NSZombieEnabled with the value YES. With this enabled any objects which are deallocated are actually turned into an instance of a 'zombie' class which will allow you to catch any messages sent to those instances.
Related
I'm new to NSZombie but I have a problem with my app crashing with EXC_BAD_ACCESS. I'm having real trouble finding the object that is causing the problem. Looking online I followed instructions to enable zombie objects.
The problem I'm having has been reported by another person on that page. Enabling zombie objects stops the bad access error but gives me no information. Nothing is printed by NSLog. Is there somewhere else I should look, or am I doing something wrong? I don't really know my way round XCode or a Mac very well as I'm mainly a C# programmer.
Any help would be most welcome.
1) Run your app on Intruments.
2) In instruments, select Object allocations tool(automatically selected if you select leaks tool).
3)Click on the little "i" on top left, within the Allocations tool.
4) Select "Enable NSZombie detection".
5) Press the record button and let your app run.
6) Go through the execution of the app untill it crashes. As soon as there is a crash, you'd see a pop up saying that there was a EXC_BAD_ACCESS. Click on the little -> on the pop up to see the object that has turned into a zombie and the line of code responsible.
Sorry I am unable to upload a screenshot, as am at work.
Expand your project Executable and right click on it. and click on GetInfo->Argument tag aat end of the window you see plus and minus sign button click on + sighn button and write
Name Value
NSZombieEnabled YES
then after execute your project and whenever crash your application click on run munu-> console you see there why your application crash. please try this may be this will help you.
I'm getting an EXC_BAD_ACCESS crash at startup and Xcode says the crash is at the NSApplicationMain line in my main.m file. The crash happens 99% of the time and when I run it with zombies enabled the crash never happens. Has anyone seen this before? How can I possibly debug this?
If you are running Xcode4 there default is to show very little of the call stack, move the slider at the bottom to the right. You may well not find any of your code but you should be able to get a good idea of what was going on. If it was a notification or selector after delay you will see that the Runloop dispatch and that will also give you a clue.
Finally, go old school, the way we did it in the day of coding forums, punch cards and only a couple of compiles a day: study your code. Know what every line of code does and why it is there.
As #Danra said, do run the Xcode Analyzer and fix all complaints.
The reason why running with zombies enabled resolves the bad access is probably that a) In this mode objects don't really get deallocated when their retain count reaches zero, and b) That your original crash is due to accessing an already deallocated object.
However with zombies enabled, instead of the crash I think you should see in the debug console the access to the deallocated object.
I also recommend using the static analyzer ("Analyze" in the XCode menus) in hope that it finds the culprit.
I am relatively new to Xcode4 and I would like to know how can I identify a double release with it.
In the debugger I see a line like *** -[NSConcreteMutableData release]: message sent to deallocated instance 0x60b63fe0.
The problem is that knowing the address doesn't help a lot identifying the object and also the object type doesn't help too much identifying it.
I read http://www.friday.com/bbum/2010/01/10/using-malloc-to-debug-memory-misuse-in-cocoa/ but I did not found this to be too successful.
You can enable the NSZombieEnabled environment variable - see How do I set up NSZombieEnabled in Xcode 4? for instructions on how to do this on Xcode 4.
What this means is that released objects are kept around in memory, so the debugger can still find out the type of objects. When the crash occurs, you are told of the object in question.
The "Zombies" Instruments tool is great for detecting bugs of this type - it actually enables NZZombieEnabled and you can use it to find out exactly which line of code the crash occurs.
You can replace the release method using categories for testing purposes, this is not designed to work like that as part of the language but in the past I have found success it trying to do some testing, usually all you find out is that an autorelease pool is releasing you object.
You are sending a release message to something which already is released or having retainCount 0. Hence, its giving such an error message. Actually, my answer over here might help.
Use the profiler for Zombies to track down the actual object. It will automatically enable NSZombies and more importantly keep a history of all release and autorelease messages.
Use Profile menu command under Product.
In the profiling template selection dialog that appears, select Zombies.
Click the Record button in the toolbar (Command-R) to begin recording. Use your app normally. If a call is made to a deallocated object, a flag is inserted in the timeline pane and a Zombie Messaged dialog appears.
Click the focus arrow next to the zombie’s memory address to display the memory history of the zombie object in the detail pane, along with corresponding reference counts and method calls.
Here is the apple documentation with pictures:
https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/EradicatingZombies.html
Try using the property retainCount. If an object has a retainCount == 0 then it will be freed. Ultimately you will not be able to send it a release message.
I'm writing a simple Cocoa Application, no core data or multiple document support. Running on a Mac Pro, OS X 10.6.6, Xcode 3.2.3.
I have reduced my application to the following code in my AppDelegate class:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel runModal];
return;
}
From within the debugger, I will run my application. As expected a somewhat not-to-useful OpenPanel will appear. I will click Cancel and it will disappear. All this is as expected. When I click [Command + Q] to Quit the application, the UI will go away but the debugger will indicate that the application is still running (as does the console output).
Based upon all the information I'm reading, I should not have to do anything else in order for this to run right. I've downloaded several examples on the Open Panel's usage but most use the deprecated methods of opening modal giving additional information as parameters. FWIW, I tried those methods and am still seeing the same result.
One last item, when the Open dialog appears, just for an instant I see a message box asking me something to the extent if I want my application to receive incoming connections. The dialog quickly disappears. I don't know if that is part of my problem or not. [Update - this deals with my Firewall being turned on.]
Yes, I'm fairly new at Objective C but not at programming in general. Any words of wisdom is greatly appreciated!
2011.02.07 - Update:
I have walked the debugger line by line without incident. There is no indication of any program failure in the console window.
I say that the debugger is still active after [Command + Q] because the Stop Process toolbar button is still enabled as is the Break button. Further the console indicates that after I tell the application to terminate (either via the menu or key command) that it is still running. The following is the Complete console output from start of run to after I Quit the application.
Program loaded.
run
[Switching to process 62370]
Running...
The Activity Monitor (system tool) will show my application terminating (no longer shows up as a process) but the Debugger will still not transition to "edit" mode - if I tell Xcode to run the debugger again, it will ask me if it's OK to Stop the current debugging session. If I was in Windows I would start looking for background threads keeping the process alive but as far as I know, NSOpenPanel should not be doing something like that.
I have further simplified the program to nothing more than creating a brand new Cocoa application and inserting the code snippet above - no other additions to the template project or updates in any way.
And lastly, when the application is run under the Leaks Performance Tool, everything runs fine when the panel is created but never used. When created and actually used though, at the end of the run I will get the following message in the tool "insufficient task_for_pid privileges (leakagent64)". Googling this hurts. If I read it right, the debugger does not have sufficient permissions to fully kill the target process ??? Now that sounds stupid but ... It does not make sense!
Another update - I just downloaded and ran FunHouse, one of the SDK sample applications that also uses NSOpenPanel. Well don't I feel special. It exhibits the same exact behavior. So from this I conclude either Apple has a bug in their code, my machine is special and messed up, and finally, it is Not my code that is at fault. That being the best part. Tomorrow, I will use a friends Mac and see if the same behavior is exhibited on his box.
This is just too weird.
I rebooted my box, took it to work and found it worked like a charm! I will assume this is fixed and has nothing to do with any other connected devices at home as compared to at work.
If it re-exhibits at home, then it is a network/device issue. Thanks all for your inputs and suggestions! Very much appreciated.
What, specifically, does the debugger say? It's possible that your program crashed, so the debugger is showing you information about the crash.
What if you omit any attempt to run an Open panel?
My application shows this error
asm CPSqliteConnectionStatementForSQL 0x30897lb3:10
and it stopped at this breakpoint in debugger
0x308971cb <+0024> mov 0x8(%edi),%eax
Does someone know about it?
The assembly code won't tell most of us anything at all, and your question is pretty light on detail about the context in which the problem occurs, such as what your app is trying to do when it crashes, whether this is always reproducible, etc. If you post more information we'll be able to help you more.
If you're debugging in Xcode, trace back up the call stack until you reach your code, then set a breakpoint there and debug your program again. When it stops at that point, try examining the related variables and see if they have the values you expect.
Edit: At the request of the asker, here is a slight clarification. When it stops at a breakpoint, the Xcode debugger window will look something like this: (from this section of Apple's Xcode Debugging Guide)
http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeDebugging/art/debugger_disassembly.jpg
The stack frames are shown in the upper-left rectangle, and you can click on a row in the table to jump to that point in the code. Grayed-out lines are those that do not have viewable source code available. Scroll down until you see a line with black text and click on it. This will show you the point at which execution left your code and entered third-party code, and you can then examine variables to get a better idea about what the problem may be. If you have further questions, I highly recommend reading through the debugging guide linked above.