Quite recently, I worked on a iPhone project that involved handling of URLs that get passed to the application at start up, e.g. by Safari or from Mail. URLs are passed into a dictionary into this UIApplication delegate method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
or
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
By default, the debugger in Xcode quits as soon as your application exits. And the debugger does not automatically attaches again when the application is launched again. So when your app gets passed a URL from another app and starts again, the debugger will not be attached, and needs to be attached manually in order to debug it.
However, when building for the device, there is an option that can be checked in the settings for the executable of your project. All you need to do is check “Wait for next launch/push notification” and Xcode will wait until the next launch or push notification before attaching GDB.

This does not work for the Simulator unfortunately. The solution I use is to have the application wait until the debugger is attached. Apple provided a little function to determine whether the debugger is attached here. So as soon as my application starts in the Simulator, I’ll let it wait:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if DEBUG
// Wait max. 10 secs for debugger to attach again:
double waitTime = 0.0;
while (AmIBeingDebugged() == NO && waitTime < 15.0)
{
[NSThread sleepForTimeInterval:0.25];
waitTime += 0.25;
}
#endif
…
}
Now, GDB in Xcode can be attached again while the application is waiting by going to the “Run” menu, then “Attach to Process” and finally picking your application’s process. For some reason, the process of the application in the Simulator doesn’t always show up in this list and you have to put in the process ID of your app’s process. Quite a hassle! So, here is a quick ‘n dirty shell script to make that part of the job easier:
#!/bin/bash
if [ -n "$1" ]
then
processid=$(ps -Ac | grep $1 | grep -o “^[0-9]*”)
if [ -n "$processid" ]
then
# echo $processid
osascript -e “tell application \”Xcode\” to activate
tell application \”System Events\”
click menu item \”Process ID…\” of ((process \”Xcode\”)’s (menu bar 1)’s ¬
(menu bar item \”Run\”)’s (menu \”Run\”)’s ¬
(menu item \”Attach to Process\”)’s (menu \”Attach to Process\”))
keystroke \”$processid\”
key code 36
end tell”
else
echo “Process not found.”
fi
else
echo “
Supply the name of the process to attach to as command line argument.
E.g.: attach Luisterpaal
“
exit
fi
It takes one argument on the command line: the name of the application (or rather the name of it’s process). It looks up the process ID with the name argument, using ps and grep. Then it uses AppleScript to control the menus of Xcode and to type in the process ID into the prompt for you. (Free to use, but as is, and on your own risk. No warranty or whatever! No error handling ;)
When debugging handleOpenURL: or didFinishLaunchingWithOptions: I now have a Terminal window open with “./attach.sh MyAppName” in it all the time. That way, attaching the debugger in Xcode is just a few keystrokes away and I have a window of 10 seconds to do that, or the application will just continue to start up.