Dlaczego czasami system Windows nie może zabić procesu?

30

Obecnie próbuję uruchomić / debugować moją aplikację w programie Visual Studio, ale nie można jej utworzyć, ponieważ ostatnia instancja app.vshost.exenadal działa. Następnie, używając Menedżera zadań, próbuję go zabić, ale pozostaje tam bez sygnału aktywności.

Poza tym szczególnym przypadkiem (być może błędem Visual Studio) jestem bardzo ciekawy technicznych powodów, dla których Windows czasami nie może zabić procesu?

Czy oświecony programista związany z systemem operacyjnym może spróbować wyjaśnić?

(I proszę, nie zaczynaj bitwy Unix / Linux / Mac przeciwko Windows.)

Néstor Sánchez A.
źródło
10
Gdybym tylko miał nikiel za każdym razem, gdy potrzebowałem odpowiedzi na to pytanie ...
Steven Oxley
3
Doceniam odpowiedzi, ale chciałbym przeczytać dewelopera systemów operacyjnych wyjaśniającego, dlaczego system operacyjny z tej epoki nie może zabić nie-rdzenia / jądra (lub innego odpowiedniego przymiotnika). Wierzyłem, że od 386 istnieje „pierścień 0” (lub coś podobnego) dający specjalne uprawnienia do niektórych kodów w stosunku do innych, myślałem, że w ten sposób proces (OS) ma władzę nad innymi. Może się całkowicie mylę, ale pytanie pozostaje bez odpowiedzi.
Néstor Sánchez A.

Odpowiedzi:

21

Przyczyną jest zwykle jakiś niereagujący sterownik, który ma niedokończone żądania We / Wy w toku.

Zobacz wpis na blogu Marka Russinowicza Procesy nie do zabicia ( archiwum )

Ian Boyd
źródło
Dzieje się tak również w Linuksie. Podczas gdy architektura x86 ma 4 pierścienie, używane są tylko dwa z nich (pierścień 3 dla przestrzeni użytkownika, pierścień 0 dla jądra). Więc wszystko jest albo trybem jądra, albo przestrzenią użytkownika, bez niczego pomiędzy. Ale możliwym obejściem są sterowniki trybu „użytkownika”, które zależą od małego niezawodnego kodu pośredniczącego trybu jądra, który jedynie wywołuje kod przestrzeni użytkownika. Sądzę, że większość sterowników drukowania i USB w systemie Windows to (sterowniki grafiki były w systemie Windows 3.1), ale przestrzeń użytkownika niesie ze sobą spadek wydajności.
LawrenceC,
Czy przemysł (Intel, AMD, ARM itp.) Nie był w stanie stworzyć „meta-ringu”, aby w końcu dać użytkownikowi (na własne ryzyko) prawdziwą możliwość zabicia procesu i pozbycia się tego problemu raz na zawsze ????
Néstor Sánchez A.
16

Jeden możliwy powód: nie możesz zabić zadania dołączonego do debuggera.

Jedynym sposobem na zatrzymanie zadania jest sam debugger.

harrymc
źródło
3
Jak dowiedzieć się, czy debugger jest dołączony i który proces jest dołączony? Ponieważ nie debuguję niczego, ale zadanie nie umrze, nie w menedżerze zadań, nie po zatrzymaniu usługi, nie za pomocą taskkill /f, nie za pomocą wmic ... call terminate... ciągle pojawia się komunikat „błąd: proces X z pid Y nie mógł zostać zakończony Nie ma uruchomionej instancji tego zadania. ”
Luc
3

Jednym z powodów byłoby to, że nie masz pozwolenia na zabicie go. Np. Jeśli proces działa jako administrator i jesteś zwykłym użytkownikiem.

Brian Lyttle
źródło
3

Otwórz stronę Właściwości projektu, przejdź do karty Debugowanie i zaznacz „Włącz debugowanie niezarządzanego kodu”. Lub odznacz opcję korzystania z procesu hosta.

Tadżou
źródło
2

Jeśli ostatni plik app.vshost.exe nadal działa, po prostu połącz się z tym procesem za pomocą debugera.

Powinien być znaleziony w menu pod Debuguj-> AttachToProcess, a następnie wybierz proces zawieszania i połącz się z nim.

Oliver Friedrich
źródło
2

Moje jedyne doświadczenie w programowaniu na poziomie systemu operacyjnego było w szkole, ale podejrzewam, że dzieje się to (lub coś podobnego):

Wystąpił błąd podczas uruchamiania ostatniej instancji, którą debuger próbował obsłużyć, ale jakiś inny problem spowodował, że to się nie powiodło (być może napotkano potwierdzenie debugowania, ale zanim można było kliknąć okno dialogowe Abort / Retry / Ignore, uruchomiono kolejną przerwę , może z powodu pustego wskaźnika). W wyniku tego, po zatrzymaniu debugowania, debuger nadal czekał na twoją odpowiedź na pierwsze stwierdzenie debugowania, więc proces nie został zakończony. Ale potem debuger zakończył się, gdy przestałeś debugować (czy zrobiłeś to?), Zamieniając proces w zombie lub jego drzewo w zombie. Podczas próby zabicia procesu zombie wystąpił błąd podobny do tego, ale menedżer zadań nie powiedział o tym:

C:\Windows\system32>taskkill /pid 9564 /f /t
ERROR: The process with PID 9564 (child process of PID 22520) could not be
terminated.
Reason: There is no running instance of the task.

Jeśli zdecydujesz się wypróbować to samo na obiekcie nadrzędnym (w moim przypadku rodzicem był proces debugowania, msvsmon.exe), nie powiedzie się to w ten sam sposób:

C:\Windows\system32>taskkill /pid 22520 /f /t
ERROR: The process with PID 9564 (child process of PID 22520) could not be
terminated.
Reason: There is no running instance of the task.
ERROR: The process with PID 22520 (child process of PID 13964) could not be
terminated.
Reason: There is no running instance of the task.

Rodzic został założony przez IDE, ale IDE przecięło pępowinę, więc teraz masz dwa procesy zombie. Nie możesz dołączyć debugera do procesu, który debugowałeś, ponieważ jest już podłączony debugger (zombie) i nie możesz dołączyć debugera do debugera (zombie), ponieważ, jak Visual Studio powie ci, kiedy spróbujesz :

Nie można dołączyć do procesu. W obecnym stanie operacja nie jest legalna.

Zombie nadal znajdują się w tabeli procesów wystarczająco dobrze, aby uniemożliwić uruchomienie innej instancji za pośrednictwem debugera, ale prawdopodobnie można uruchomić inną instancję poza środowiskiem IDE.

Rozwiązuje to bardziej konkretny problem polegający na tym, że VS tworzy proces zombie. Ale procesy zombie często nie umierają. Cóż, często na Windowsie, czasem na Linuksie, dopóki nie zastrzelisz ich strzelbą. Czy to było zamknięcie? Ale uważaj na przypadkową aplikację oczekujących aktualizacji systemu Windows.

Byłem podekscytowany niektórymi wcześniejszymi odpowiedziami, które sugerowały dołączenie się do debuggera, ale powyższy wynik jest wynikiem. Przesyłam więc swoją odpowiedź i uruchamiam ponownie, aby wyczyścić tabelę procesów.

hlongmore
źródło
Dzięki, to z pewnością najlepsza odpowiedź, która pasuje do mojego problemu.
Pablo Ariel
-1

Możesz!

Korzystanie z ProcessHacker (kliknij proces prawym przyciskiem myszy) -> Terminator.

Valmond
źródło
-1

Jeśli używasz VS do debugowania procesu i zabijasz go za pomocą menedżera zadań, a następnie VS nie może sobie z tym dobrze poradzić.

Więc VS nadal debuguje proces docelowy, ale nie można po prostu nacisnąć zatrzymać procesu w VS. Wystarczy wyjść z VS i zobaczysz, że proces się kończy.

VictorV
źródło