Xcode在运行iOS测试/模拟器后离开僵尸进程

时间:2012-11-03 13:44:49

标签: xcode zombie-process

在iOS应用程序上使用Xcode几天后,我注意到有超过100个僵尸进程闲置。似乎每次运行单元测试都有一个,每次我在模拟器中运行完整的应用程序时可能有一个。这是一个样本(清理和截断):

> ps -efj | grep $PRODUCT_NAME
  502  2794   236   0 Wed12AM ??         0:00.00 (MyProduct)  me            2794      0    1 Z      ?? 
  502  2843   236   0 Wed01AM ??         0:00.00 (MyProduct)  me            2843      0    1 Z      ?? 
  502  2886   236   0 Wed01AM ??         0:00.00 (MyProduct)  me            2886      0    1 Z      ?? 
...
  502 13711   236   0 Thu11PM ??         0:00.00 (MyProduct)  me           13711      0    1 Z      ?? 
  502 13770   236   0 Thu11PM ??         0:00.00 (MyProduct)  me           13770      0    1 Z      ?? 
  502 14219   236   0 10:35AM ??         0:00.00 (MyProduct)  me           14219      0    1 Z      ?? 
  502 14280   236   0 10:38AM ??         0:00.00 (MyProduct)  me           14280      0    1 Z      ?? 

倒数第二列中的Z表示它们是僵尸进程。第三列中的236是父PID,在这种情况下属于我的用户的launchd

请注意,某些流程需要多天才能完成。在此期间我已经退出并重新打开了Xcode几次。

有谁知道为什么会发生这种情况,或者这是否应该引起警报?

2 个答案:

答案 0 :(得分:15)

在一些特别沉重的Xcode会话之后,我的MBP听起来像是被要求执行STARNET初始化程序,我决定花几分钟时间研究这个僵尸程序的废话...毕竟,一个Unix盒子可以' t fork是一个无用的Unix盒子。我可能有一些好消息。希望我们能看到。在10.8.2上运行Xcode 4.6。

无论使用GDB还是使用LLDB,僵尸问题似乎都会发生。在模拟器中运行的应用程序由调试进程拥有 - GDB或LLDB情况下的“debugserver”。当你点击“停止”时,在模拟器中运行的应用程序进程变为僵尸。这听起来像是一个不干净的关机序列。

在预感而不是点击“停止”时,我暂停了应用程序,并在调试控制台(在我的情况下为LLDB)中,我使用“进程分离”从正在运行的应用程序中取消连接。快速ps验证调试服务器不再运行...到目前为止一切顺利!现在,应用程序仍然在模拟器中运行,只是没有进行调试。事实上,现在点击“停止”按钮是一个无操作。

在模拟器中点击主页按钮返回跳板,然后双击主页按钮并手动关闭应用程序。转到你的命令行,寻找僵尸......没有僵尸!耶。

所以...下一步是看看是否有合理的方法通过python脚本等执行此类或类似的关闭过程。如果您使用的是GDB,那么该课程无济于事。如果我可以通过一个调试控制台命令进行干净关闭,那么只需要习惯不按下损坏的停止按钮。也许有资源黑客完全禁用它...... :)

编辑#1:几个有趣的花絮......

1。)点击xcode中的Stop按钮直接杀死调试和应用程序进程 - 没有任何尝试进行干净关闭。应用程序委托applicationWillTerminate和applicationDidEnterBackground中的Printf调试显示正在运行的应用程序因偏见而被杀死 - 控制台中没有显示NSLog。

2。)在调试控制台中调用[UIApplication terminateWithSuccess]将导致应用程序“正常”终止,但仍留下僵尸......有趣的是,如果你设置了断点,应用程序将不会终止:

(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) 

所以应用程序会经历某种关闭过程,并且会在控制台中终止显示,但我们仍然有一个僵尸,所以它仍然不是一个干净的关闭。

我认为整个事情都与应用程序在iOS运行时中进入后台有关。直接调整进程时(通过Stop按钮,kill命令,调试控制台等等)iOS运行时不允许进行正确的关闭和清理 - 事实上,跳板仍然认为应用程序在后台运行即使过程不再存在。事实上,我们的iOS和OS X运行时是同一个 - 因此推出拥有僵尸。

所以我认为所有这一切的解决方案是在iOS级别确定一个干净的关闭过程,并且至少能够通过调试控制台执行该过程。要更多地了解UIApplicationExitsOnSuspend标志,看看我是否可以在运行时设置必要的位(而不是plist),以便在调试分离时干净地关闭应用程序......

答案 1 :(得分:3)

他们并没有特别占用很多空间。

这似乎是Xcode机器不正确地杀死子进程的工件。

我有同样的问题,但我注意到,在我的情况下,僵尸属于ppid 271,它是以我的名义调用launchd,而不是整个系统。

我很好奇如果我杀了那个过程会发生什么。

无论如何,退出可能清除僵尸。在我的书中,肯定会重新启动,但这是可以避免的。


哦,非常糟糕不要杀死你的发布者,它会毫不客气地杀死你的会话,但不会让你回复,就像给你一个登录屏幕。

我必须看看因为停止Xcode而让我离开了僵尸。看来这里可能会有一些愚蠢的事情。你的过程不会等待孩子,它会变得僵尸。如果父母去世了,我认为接下来的事情会得到它,在这种情况下是启动的。 Launchd应该等待(),但也许这会让人感到困惑?