How to debug EXC_BAD_ACCESS error using Profile in Xcode - xcode

After I received a exc_bad_access error I read this tutorial: http://www.ioslearner.com/debugging-exc_bad_access-error-xcode-instruments/ and followed the steps:
Run Profile
Choose Zombies
Everything looks the same on my computer except that I do not get the Zomie Signal.
In order to make sure I did not forget a step I tried it with the example code provided in the Tutorial. There I see the Zombi Signal
So how do I get the zombie signal in my project using Xcode -> Profile?
This is the sample code I use:
I am well aware that the two releases cause the error. Again the question is how get the "Zombie Message" in the Profile using Xcode:
NSArray *currentRestaurant = [restaurants objectAtIndex:i];
RestauInfo *restauInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"RestauInfo"
inManagedObjectContext:context];
[restauInfo release];
restauInfo.Name = [currentRestaurant objectAtIndex:0];
restauInfo.Cuisine = [currentRestaurant objectAtIndex:1];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
[restauInfo release];// - this release would cause an EXC_BAD_ACCESS
Another question is: Why do I get bad_access at the second release - and not when accessing restauInfo after the first release?

I found another way detecting faults in memory management:
In Xcode you can choose "Run", "Test", "Profile" and "Analyze"
(By pressing and holding the run Button in the upper left corner)
Running the analyze reveals memory management errors - such as
over releasing
leaks

You are overreleasing restauInfo, its an autoreleased object and you call -release manually twice, causing your crashes.
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSEntityDescription_Class/NSEntityDescription.html

Related

Close and launch with different command line parameters/arguments

I am running a .app and I need to "restart" it so to speak. Basically I need to tell it to close, then after closing, it should launch the path i tell (which is to itself) with some command line arguments. Is this possible with cocoa? Im getting stuck at the part where my app is closing then closed, then I cant get it back.
My code is in js-ctypes, but here is the objc pseudo code:
default_center = [NSDistributedNotificationCenter defaultCenter];
shared_workspace = [NSWorkspace sharedWorkspace];
notification_center = [[NSWorkspace sharedWorkspace] notificationCenter];
[notification_center addObserver:selector:name:object: ***, ***, NSWorkspaceDidLaunchApplicationNotification, NIL]
And in my observr when it responds with completion of quit it has code to launch. But as my app is closed it never gets to the observer responder.
Here
Thanks
You didn't mention any reason that you cannot launch a second instance of your app from the first instance, rather than the chicken & egg approach of trying to restart after you've quit... I have this code in my AppWillTerminate function where I have a situation like yours:
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:appUrl options:NSWorkspaceLaunchNewInstance configuration:nil error:&error];
( To get the AppWillTerminate to be called in the first place, I had to disableSuddenTermination before calling [app quit] )
There's also some flag in the app's plist file like "allow multiple instance" or something.
Also, KNOW THIS: if your app is sandboxed, this will not work UNLESS it is code signed with an AppleStore given id, or with a Developer ID Application id. Also, it won't work on X.7 no matter what, when sandboxed.
METHOD TWO,
is to create a "Helper App". Your KillerApp goes through the Quit process, and right before it dies, it launches "HelperApp", which is a tiny command line tool which waits for KillerApp to really die, then relaunches it.
In XCode, the code for the HelperApp, a "Command line tool", is like this:
#import <Cocoa/Cocoa.h>
int main( int argc , char *argv[] ) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
pid_t parentPID = atoi(argv[2]);
ProcessSerialNumber psn;
while ( GetProcessForPID(parentPID, &psn) != procNotFound )
sleep(1);
NSString* appPath = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
BOOL success = [[NSWorkspace sharedWorkspace] openFile:[appPath stringByExpandingTildeInPath]];
if ( ! success )
NSLog(#"Error: could not relaunch application at %#", appPath);
[pool drain];
return (success) ? 0 : 1;
}
As you can see, you call the HelperApp with a couple parameters from your KillerApp... And in the case where you don't need to be sandboxed, that's about it.
If you DO need sandboxing, then it gets more complicated, of course. You need to create a "privileged helper tool", and thank goodness there is sample code for it.
"SMJobBless" is the Apple sample code project which outlines how to do this, but it's kind of weird-- it doesn't actually DO anything. Thankfully, somebody took that project and created "SMJobBlessXPC" from it, which really does finish the job, ( and when you get it working, your KillerApp can actually communicate with your HelperApp ). The downside is that you need to exactly maintain the plist files of the two apps in terms of code signing.

Implementing GameKit.framework on OSX, cannot authenticate localPlayer

I'm attempting to implement GameKit in my OSX game. Unfortunately I can't find much information about how to do this; all tutorials seem to be iOS (though the documentation clearly states "Game Center is available on iOS and OS X").
Everything is compiling fine; the problem comes when I try to authenticate the local user:
[[GKLocalPlayer localPlayer] setAuthenticateHandler:^(id viewController, NSError *error) {
if(error) {
DLog(#"Error: %#",error);// This is always returning an error
}
else if(viewController) {
// WHAT DO I DO HERE??
}
}];
I have 2 problems:
First, the handler always gets an error: Error Domain=GKErrorDomain Code=6 "The requested operation could not be completed because local player has not been authenticated." UserInfo=0x10103bc70 {NSLocalizedDescription=The requested operation could not be completed because local player has not been authenticated.}.
Second, I don't know how to present the view controller.
On the iPhone, this code works fine: there's no error, and I simply present the viewController (which is the login screen).
I'm sorry, and I realize that my answer is almost a year late, but in case it may still be relevant for others who are still asking this question like myself. Ed Marty is mostly correct, but what I've discovered that works for me is this.
[[GKLocalPlayer localPlayer] setAuthenticateHandler:^(NSViewController < GKViewController > viewController, NSError *error) {
if(error) {
NSLog(#"Error: %#",error);
}
else if(viewController) {
GKDialogController *presenter = [GKDialogController sharedDialogController];
presenter.parentWindow = myWindow;
[presenter presentViewController:viewController];
}
}];
The main difference is using NSViewController conforming to GKViewController instead of id.(Also, I used NSLog instead of DLog, but that isn't too important).
"I have found, however, that this is completely useless, and it presents the login dialog before it even calls the handler."
To make sure that it works, set up a new Game Center account through your app. When you run your program and it loads a window for you to sign in, press "Create New Apple ID" even if you already have an Apple ID. The button may not work, so if that's the case, open up Game Center and press "Create New Apple ID." Either way, your objective is to create a "Sandboxed" Game Center account, which you can learn more about here: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/TestingYourGameCenter-AwareGame/TestingYourGameCenter-AwareGame.html#//apple_ref/doc/uid/TP40008304-CH17-SW1
You can tell if the account is Sandboxed if when you are reading the terms and conditions, the word "Sandbox" appears on a yellow banner in the top left. Once again, I'm sorry I'm late, but hopefully this clears the topic for all future viewers.
P.S. I'm sorry that the code did not format properly.
I have found that the GameKit documentation for OSX is woefully lacking, misleading, and sometimes downright wrong. That said, here's what you're supposed to do, according to this document:
[[GKLocalPlayer localPlayer] setAuthenticateHandler:^(id viewController, NSError *error) {
if(error) {
DLog(#"Error: %#",error);// This is always returning an error
}
else if(viewController) {
GKDialogController *presenter = [GKDialogController sharedDialogController];
presenter.parentWindow = myWindow;
[presenter presentViewController:viewController];
}
}];
I have found, however, that this is completely useless, and it presents the login dialog before it even calls the handler.

App Crashing on Simulator and Device but not when Profiling

The app crashing with signal SIGABRT (the debugger output is child already added. It can't be added again) in the simulator and on the device. Runs fine when I profile the app in Xcode while running it on the simulator or the device. Why is this?
Update: I've figured out that this line of code is causing the problem:
Mover *moverObject = [[[Mover alloc] init] autorelease];
NSMutableArray * array = [moverObject moveToward:startPoint :finalPoint]//<-- This is the problem
moveToward is method that returns a NSMutableArray containing the points from the startPoint to the finalPoint. This worked fine early today but after I started testing something new I guess I broke it. I made no changes in the actual Mover.h/.m just in the GameLayer.m (where I was adding code). I'm not sure what I added to cause the problem.
Update 2: I did some more digging using breakpoints and I found that
GameLayer *gameLayerObject = [[GameLayer alloc] init];<-- This causes the crash
Inside mover.m where the method moveToward:: is, this is the furthest it will go without crashing. Again the error is child already added. It can't be added again. Why does this happen?
This may just be coincidence. Hard to say because you didn't post any code.
The error message is clear though: you're trying to addChild the same node more than once, either to the same parent or to a different parent. Check your code for situations where this can occur.

Xode 4.5 Hello World example doesn't work

I am pretty much an XCode beginner, and I therefore tried the, "Hello World" example given in the XCode documentation: Quick Start Guide: Tutorial: Using Xcode to Write “Hello, World!” for OS X.
I am using XCode 4.5.1 from whose documentation I took this example using OS 10.8.2. I followed the instructions; the example didn't work. It produced the window but not the "hello world" printing. The relevant code is:
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
NSString *hello = #"Hello, World!";
NSPoint point =NSMakePoint(15, 75);
NSMutableDictionary *font_attributes = [[NSMutableDictionary alloc] init];
NSFont *font = [NSFont fontWithName:#"Futura-MediumItalic" size:42];
[font_attributes setObject:font forKey:NSFontAttributeName];
[hello drawAtPoint:point withAttributes:font_attributes];
[font_attributes release];
}
There are two notable things. The last line of this code gives an error:
release is unavailable: not available in automatic reference counting mode
So I commented this line out and ran the program. The window appeared, but no "Hello World". A long message appeared in the All Output, part of which read:
"/Users/me/Library/ScriptingAdditions/YouHelper.osax/Contents/MacOS/YouHelper: no matching architecture in universal wrapper
Hello: OpenScripting.framework - scripting addition "/Users/me/Library/ScriptingAdditions/YouHelper.osax" declares no loadable handlers."
Am I doing something dumb, or am I using the wrong example?
You have to remove [font_attributes release]; at the end of your code.
release, retain, alloc and dealloc are not available in ARC(Automatic Reference Counting). This is what the error says.
And for the second error you should remove anything that is referring to AppleScript and similar scripting addons for the app.
Without seeing you project it's difficult to find out what's wrong with it. My guess is: You forgot to specify the custom view's class in IB (Step 12 in "Design the User Interface").

Getting Strange video warning from my IKPictureTaker App

I have a simple little osx app that just starts up an IKPictureTaker and then saves the resulting picture as a .tiff file. It all seems to work fine but everytime I take the picture I get this error repeatedly:
2009-11-10 12:25:38.890 Take A Picture[855:9c23] *** QTCaptureSession warning: Session received the following error while decompressing video: Error Domain=NSOSStatusErrorDomain Code=-67441 "Operation could not be completed. (OSStatus error -67441.)". Make sure that the formats of all video outputs are properly configured.
The code is pretty simple:
- (void)awakeFromNib
{
IKPictureTaker *sharedPictureTaker = [IKPictureTaker pictureTaker];
[sharedPictureTaker setValue:[NSNumber numberWithBool:YES] forKey:IKPictureTakerShowEffectsKey];
[sharedPictureTaker beginPictureTakerWithDelegate:self didEndSelector:#selector(pictureTakerDidEnd:returnCode:contextInfo:) contextInfo:nil];
}
- (void) pictureTakerDidEnd:(IKPictureTaker *) picker
returnCode:(NSInteger) code
contextInfo:(void*) contextInfo
{
NSImage *image = [picker outputImage];
NSString *folder = #"/Users/Mike/Library/Application Support/file.tiff";
folder = [folder stringByExpandingTildeInPath];
[[image TIFFRepresentation] writeToFile:#"~/Library/Application Support/file2.tiff" atomically:NO];
}
Sounds like there might be some configuration issue with your machine. Are you able to test it on another? Is there anything else going on in your app? Do you get the same thing if you select different kinds of image files or only when capturing?
Your strings are a bit mixed up in the writing method, but that aside the code works fine for me in an otherwise virgin app.

Resources