24

iOSアプリでXcodeを数日間使用した後、100を超えるゾンビプロセスがぶら下がっていることに気づきました。単体テストを実行するたびに1つ、シミュレーターでアプリ全体を実行するたびに1つあるようです。サンプル(クリーンアップおよび切り捨て)は次のとおりです。

> 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      ?? 

最後から2番目の列のZは、それらがゾンビプロセスであることを示します。launchd3番目の列の236は親PIDであり、この場合は私のユーザーに属します。

一部のプロセスは数日前のものであることに注意してください。この期間中にXcodeを数回終了し、再開しました。

なぜこれが起こるのか、またはこれが警報の原因になるべきかどうか誰かが知っていますか?

4

2 に答える 2

15

MBP が STARNET Init Procedure の実行を要求されているように聞こえる、特に負荷の高い Xcode セッションをいくつか行った後、私は数分間、このゾンビ プロセスのナンセンスを調べてみることにしました...結局のところ、フォークできない Unix ボックスは役に立たない Unix ボックス。良い知らせがあるかもしれません。うまくいけば、私たちは見るでしょう。ここで 10.8.2 で Xcode 4.6 を実行します。

ゾンビの問題は、GDB または LLDB の使用に関係なく発生するようです。シミュレータ内で実行されているアプリは、デバッグ プロセス (GDB、または LLDB の場合は「デバッグ サーバー」) によって所有されます。「停止」を押すと、シミュレーターで実行されているアプリ プロセスがゾンビになります。これは、クリーンでないシャットダウン シーケンスのように聞こえます。

「停止」を押すのではなく、直感でアプリを一時停止し、デバッグ コンソール (私の場合は LLDB) で、「プロセス デタッチ」を使用して実行中のアプリから接続を解除しました。簡単な ps は、debugserver が実行されていないことを確認します...これまでのところ、とても良いです! 現在、アプリはまだシミュレーター自体で実行されており、デバッグ中ではありません。実際、停止ボタンを押してもノーオペレーションになりました。

シミュレーターでホーム ボタンを押してスプリングボードに戻り、ホーム ボタンをダブルクリックしてアプリを手動で閉じます。コマンド ラインに移動し、ゾンビを探します... ゾンビではありません! わーい。

だから...次のステップは、Pythonスクリプトなどを介してこれまたは同様のシャットダウン手順を実行する合理的な方法があるかどうかを確認することです.GDBを使用している場合、それは役に立ちません. 単一のデバッグ コンソール コマンドでクリーン シャットダウンを実行できる場合は、壊れた [停止] ボタンを押さないように慣れるだけです。たぶん、それを完全に無効にするリソースハックがあります... :)

編集 #1: いくつかの興味深い情報...

1.) xcode で停止ボタンを押すと、デバッグ プロセスとアプリ プロセスが完全に強制終了されます。クリーン シャットダウンを実行しようとする試みはまったくありません。アプリ デリゲート 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 ランタイム内でアプリがバックグラウンドに移行することに関係していると考えています。プロセスを直接変更する場合 (停止ボタン、kill コマンド、デバッグ コンソールなどを介して)、iOS ランタイムは適切なシャットダウンとクリーンアップを実行できません。プロセスはもう存在しません。たまたま、iOS と OS X のランタイムが 1 つになっているため、launchd がゾンビを所有しています。

したがって、これらすべての解決策は、iOS レベルでクリーンなシャットダウン手順を決定し、少なくともデバッグ コンソールを介してそれを実行できるようにすることだと思います。UIApplicationExitsOnSuspend フラグを詳しく調べて、実行時に (plist ではなく) 必要なビットを設定して、デバッグ デタッチ時にアプリを正常にシャットダウンできるかどうかを確認します...

于 2013-03-24T17:36:48.073 に答える
3

彼らは特に多くの部屋を占有しません。

これは、サブプロセスを不適切に強制終了する Xcode 機構のアーティファクトのようです。

私は同じ問題を抱えていますが、私の場合、システム全体ではなく、私の名前で launchd を呼び出している ppid 271 にゾンビが属していることに注意してください。

そのプロセスを強制終了またはハップするとどうなるか興味があります。

いずれにせよ、ログアウトすることでおそらくゾンビは一掃されるでしょう。そして確かに再起動しますが、私の本ではそれは避けるべきです.


ああ、それはかなりうまくいきませんでした。launchdを強制終了しないでください。無意識にセッションを強制終了しますが、ログイン画面を表示するなど、セッションを元に戻すことは何もしません。

Xcodeを停止したためにゾンビを置き去りにしたことを確認する必要があります。ここにはいくつかのばかげたことがあるようです。プロセスが子を待たない場合、ゾンビになります。親が死んだ場合、次の行がそれを取得すると思いますが、この場合は launchd です。Launchd はそれを待つ必要がありますが、混乱している可能性がありますか?

于 2012-11-15T11:33:09.150 に答える