2012-11-03 12 views
24

Po kilku dniach pracy w Xcode na urządzeniu z iOS zauważyłem, że wokół jest ponad 100 procesów zombie. Wydaje się, że jest jeden za każdym razem, gdy przeprowadzałem testy jednostkowe, i prawdopodobnie za każdym razem, gdy uruchomiłem pełną aplikację w symulatorze. Oto próbka (oczyszczona i obcięta):Xcode opuszcza procesy zombie po uruchomieniu testów i symulatorów iOS

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

Symbol Z w kolumnie drugiej do ostatniej wskazuje, że są procesami zombie. 236 w trzeciej kolumnie jest rodzicielskim PID, który należy do mojego użytkownika launchd w tym przypadku.

Należy pamiętać, że niektóre procesy mają kilka dni. Kilka razy przerwałem i ponownie otworzyłem Xcode w tym okresie.

Czy ktoś wie, dlaczego tak się dzieje, czy może to być powodem do niepokoju?

+0

Mam 437 zombie i liczę. Jedynym problemem, który stanie się wcześniej czy później, jest to, że nie możesz rozpocząć nowych procesów, więc miej na uwadze zombie. Zajęło mi trochę czasu, aby dowiedzieć się, dlaczego nie mogę się więcej skompilować. Zobacz także http://stackoverflow.com/a/7860828/457406 –

+0

@esker Czy kiedykolwiek zastanawiałeś się nad rozwiązaniem tego problemu oprócz ponownego uruchomienia? –

+0

Nie, o ile rozumiem, tak to po prostu działa. Zobacz poniższą dyskusję na temat procesów zombie kończących się przynależnością do 'launchd'. Wydaje się, że jedynym potencjalnym problemem może być po jakimś czasie wyczerpywanie 'pid's. –

Odpowiedz

3

Nie zajmują szczególnie dużo miejsca.

Wygląda na to, że artefakt maszyny Xcode niewłaściwie zabija podprocesy.

Mam ten sam problem, ale zauważam, że zombie należą, w moim przypadku, ppid 271, który jest inwokacją launchd pod moim nazwiskiem, zamiast całego systemu.

Jestem ciekawy, co może się stać, jeśli zabiję lub pobiorę ten proces.

W każdym przypadku wylogowanie spowoduje prawdopodobnie wyczyścić zombie. I na pewno zresetowanie będzie, ale tego należy unikać, w mojej książce.


Och, że poszedł dość słabo. Nie zabijaj uruchomionego, bezceremonialnie zabija twoją sesję, ale nie robi nic, aby pozwolić ci ją odzyskać, na przykład daje ci ekran logowania.

Będę musiał sprawdzić i zobaczyć, czy zostawiłem zombie z powodu zatrzymania Xcode. Wygląda na to, że może tu być kilka głupich rzeczy. To twój proces nie czeka na dziecko, staje się zombie. Jeśli rodzic umiera, to wydaje mi się, że następna rzecz, która w tym przypadku jest uruchamiana, pojawia się. Uruchomiony powinien poczekać() na to, ale może to się mylić?

+8

'Nie zajmują one szczególnie dużo miejsca. Prawda, że ​​wymaga czegoś ważniejszego: zjada liczbę procesów, które można utworzyć. 'fork' nie powiedzie się, więc nie możesz zdać exec' kill' – 2mia

+0

@ 2mia ma całkowicie rację, po kilku dniach bez restartowania mojego systemu deweloperskiego, cały czas otrzymuję błąd widelca. –

+0

@ 2mia ma rację, po kilku dniach bez ponownego uruchamiania, często pojawia się błąd widelca. Ponowne uruchomienie jest bardzo denerwujące. Każda inna poprawka/obejście, które nie wymaga zwiększenia dozwolonych procesów? –

15

Po kilku szczególnie ciężkich sesjach Xcode, w których mój MBP brzmiał, jakby był poproszony o wykonanie procedury Init gry STARNET, postanowiłem poświęcić kilka minut na zaglądanie w ten proces bzdurnego procesu ... w końcu Unix, który może Widelec jest bezużytecznym pudełkiem uniksowym. I może mieć dobre wieści. Mam nadzieję, że zobaczymy. Uruchomienie Xcode 4.6 na 10.8.2 tutaj.

Wydaje się, że problem z zombie dzieje się niezależnie od użycia GDB lub LLDB. Aplikacja działająca w symulatorze jest własnością procesu debugowania - albo GDB, albo "debugserver" w przypadku LLDB. Po naciśnięciu "Stop" proces aplikacji uruchomiony w symulatorze przechodzi zombie. To brzmi jak nieczysta sekwencja zamykania.

W przeczuciu zamiast "Stop" zatrzymałem aplikację, aw konsoli debugowania (LLDB w moim przypadku) odłączyłem się od uruchomionej aplikacji za pomocą "procesu odłączania". Szybki serwer ps weryfikuje serwer debugserver, który nie jest już uruchomiony ... do tej pory taki dobry! Teraz aplikacja nadal działa w samym symulatorze, ale nie w debugowaniu. W rzeczywistości, naciśnięcie przycisku Stop teraz nie jest opcją.

W symulatorze naciśnij przycisk home, aby powrócić do trampoliny, a następnie kliknij dwukrotnie przycisk strony głównej i ręcznie zamknij aplikację. Idź do linii poleceń i szukaj zombie ... bez zombie! Yay.

Więc ... następnym krokiem jest sprawdzenie, czy istnieje rozsądny sposób wykonania tej lub podobnej procedury zamykania za pomocą skryptu Pythona itp. "Kurs, który nie pomoże, jeśli korzystasz z GDB. Jeśli mogę zrobić czyste zamknięcie za pomocą pojedynczej komendy debugowania konsoli, to tylko kwestia przyzwyczajenia się do nie trafienia uszkodzonego przycisku Stop. Może istnieje hack zasobów, aby ją wyłączyć całkowicie ... :)

EDIT # 1: Kilka ciekawych ciekawostki ...

1.) Uderzanie przycisk Stop w Xcode tylko wręcz zabija procesy i debugowania aplikacji - - nie próbujemy robić czystego postoju. Printf debug w aplikacji delegata aplikacjiWill Terminate i applicationDidEnterBackground pokazują, że uruchomiona aplikacja jest zabijana z uprzedzeniem - w konsoli nie wyświetlają się komunikaty NSLogs.

2.) W konsoli debugowania wywołanie [UIApplication terminateWithSuccess] spowoduje, że aplikacja do wypowiedzenia „prawidłowo”, ale nadal pozostawia zombie ... Co ciekawe, jeśli masz breakpoint zestaw, aplikacja nie zakończy:

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

Dzięki temu aplikacja przechodzi jakiś proces zamykania, a zakończy programy w konsoli, ale nadal mamy zombie, więc nadal nie jest to czyste zamknięcie.

Myślę, że to wszystko ma związek z tym, że aplikacja będzie działać w tle w środowisku wykonawczym iOS. Podczas bezpośredniego zmieniania procesów (za pomocą przycisku Stop, komendy kill, debugowania konsoli itp.) Środowisko wykonawcze iOS nie może wykonać właściwego wyłączenia i czyszczenia - w rzeczywistości trampolina nadal uważa, że ​​aplikacja działa w tle, nawet gdy proces już nie istnieje. Tak się składa, że ​​nasze środowiska uruchomieniowe dla systemu iOS i OS X są jednym w tym samym - w związku z tym uruchomiliśmy posiadanie zombie.

Uważam, że rozwiązaniem tego wszystkiego jest określenie procedury czyszczenia na poziomie iOS i przynajmniej możliwość wykonania tego za pomocą konsoli debugowania. Będziesz wyglądać bardziej w flagę UIApplicationExitsOnSuspend, sprawdź, czy mogę ustawić wymagane bity w czasie wykonywania (w przeciwieństwie do plist), aby wyłączyć aplikację po odłączeniu debugowania ...

+0

Bardzo interesująca odpowiedź. Jak dotąd najbardziej kompletna, jaką kiedykolwiek widziałem na ten temat. Czekamy na rozwój! – Frizlab

+0

Dzięki za szczegóły. Czy ma to sens, aby launchd automatycznie zbierał zombie, które mu podlegają? (Lub przynajmniej mieć opcję launchctl, aby to zrobić?) –

Powiązane problemy