After some particularly heavy Xcode sessions where my MBP sounded like it was being asked to execute the STARNET Init Procedure, I decided to spend a few minutes looking into this zombie process nonsense... after all, a Unix box that can't fork is a useless Unix box. I may have some good news. Hopefully, we'll see. Running Xcode 4.6 on 10.8.2 here.
The zombie issue appears to happen regardless of GDB or LLDB usage. The app running within the simulator is owned by the debug process -- either GDB, or "debugserver" in the case of LLDB. When you hit "Stop" the app process running in the simulator goes zombie. This sounds like an unclean shutdown sequence.
On a hunch rather than hitting "Stop", I paused the app, and in the debug console (LLDB in my case) I unattached from the running app using "process detach". A quick ps verifies debugserver is no longer running... so far so good! Now, the app is still running in the simulator itself, just not under debug. In fact, hitting the Stop button now is a no-op.
In the simulator hit the home button to get back to springboard, then double-click the home button and manually close the app. Go to your command line and look for the zombie... no zombie! Yay.
So... next step is to see if there's a reasonable way to execute this or similar shutdown procedure via python script etc. 'Course that doesn't help if you're on GDB. If I can do a clean shutdown via a single debug console command then it's just a matter of getting used to not hitting the broken Stop button. Maybe there's a resource hack to disable it altogether... :)
EDIT #1: couple of interesting tidbits...
1.) Hitting Stop button in xcode just outright kills the debug and app processes -- there's no attempt to do a clean shutdown whatsoever. Printf debug in app delegate applicationWillTerminate and applicationDidEnterBackground shows that the running app is killed with prejudice -- no NSLogs shown in the console.
2.) In debug console calling [UIApplication terminateWithSuccess] will cause the app to terminate "properly", but still leaves a zombie... interestingly if you have a breakpoint set, the app won't terminate:
(lldb) expression
Enter expressions, then terminate with an empty line to evaluate:
[(UIApplication *)[UIApplication sharedApplication] terminateWithSuccess]
error: Execution was interrupted, reason: breakpoint 2.1.
The process has been returned to the state before execution.
(lldb) breakpoint disable 2.1
1 breakpoints disabled.
(lldb) expression
Enter expressions, then terminate with an empty line to evaluate:
[(UIApplication *)[UIApplication sharedApplication] terminateWithSuccess]
2013-03-25 01:28:00.186 iPhone Testbed[9481:c07] -[AppDelegate applicationWillTerminate:]
(lldb)
So app goes through some sort of shutdown process, and the will terminate shows in console, but we still have a zombie, so it's still not a clean shutdown.
I'm thinking this whole thing has to do with the app going to the background within iOS runtime. When munging processes directly (via Stop button, kill command, debug console stuff, etc. etc.) iOS runtime is not allowed to do proper shutdown and cleanup -- in fact, springboard still thinks the app is running in the background even when the process no longer exists. It just so happens our iOS and OS X runtimes are one in the same -- hence launchd owning the zombie.
So I think the solution to all of this is determining a clean shutdown procedure at the iOS level and at least be able to execute that via debug console. Gonna look more into UIApplicationExitsOnSuspend flag, see if I can set the necessary bits at runtime (as opposed to plist) to get the app shutdown cleanly upon debug detach...
launchd
. It appears that the only potential problem could be running out ofpid
s after a while. – Rambouillet