Jak mogę ustalić, czy aplikacja nie odpowiada?

11

Mam aplikację na OSX, która wielokrotnie przechodzi w stan braku odpowiedzi i musi zostać zabita siłą. Miałem nadzieję zautomatyzować go, ale podczas sprawdzania procesu za pomocą ps nie widzę niczego, co odpowiada stanowi Nie odpowiadam. Spojrzałem na wskaźnik stanu , ale aplikacja pokazuje jako S, czy odpowiada, czy nie.

stan Stan jest podawany przez ciąg znaków, na przykład `` RWNA ''. Pierwszy znak wskazuje stan uruchomienia procesu:

  • I Oznacza proces bezczynności (spanie dłużej niż około 20 sekund).
  • R Oznacza uruchamialny proces.
  • S Oznacza proces, który śpi przez mniej niż około 20 sekund.
  • T Oznacza zatrzymany proces.
  • U Oznacza proces w nieprzerwanym oczekiwaniu.
  • Z Oznacza martwy proces (`` zombie '').

Jak mogę ustalić, czy proces nie odpowiada, jak robi to Menedżer aktywności?


Jestem również otwarty na rozwiązania AppleScript.

Krzyż
źródło

Odpowiedzi:

9

Stan Brak odpowiedzi nie jest stanem procesu, ale raczej proces przestał komunikować się z menedżerem okien / silnikiem graficznym. Można go związać w pętli, zawiesić na gnieździe, zdalny plik, wszystko, co powoduje, że wraca do głównej pętli, która obsługuje zdarzenia. Menedżer okien zauważa, że ​​zdarzenia są w kolejce, a zatem oznacza je jako „Nie odpowiada”

Może być konieczne napisanie małego programu X11, który wysyła fałszywe zdarzenia do procesu, a następnie zabicie go, jeśli nie zareaguje.

JvO
źródło
Może pisanie czegoś przy użyciu AppleScript, co jako dostęp na poziomie interfejsu użytkownika.
Matthieu Riegler,
@MatthieuRiegler Jak zrobiłbyś to w AppleScript?
C. Ross
Podałem przykład w innej odpowiedzi.
Matthieu Riegler,
4

Oto skrypt AppleScript wykorzystujący skrypty interfejsu użytkownika, który szuka nie reagującego procesu i zabija go.

Będzie działać z monitorem aktywności Mavericks. Ale ponieważ jest to skrypt interfejsu użytkownika i ponieważ zmieniono interfejs użytkownika Monitora aktywności, najprawdopodobniej nie będzie działać ze starszym OS X bez drobnych modyfikacji.

tell application "Activity Monitor" to run  --We need to run Activity Monitor
tell application "System Events" to tell process "Activity Monitor"
    tell radio button 1 of radio group 1 of group 1 of toolbar 1 of window 1 to click --Using the CPU View 
    tell outline 1 of scroll area 1 of window 1 -- working with the list 
        set notResponding to rows whose value of first static text contains "Not Responding" -- Looking for Not responding process
        repeat with aProcess in notResponding
            set pid to value of text field 5 of aProcess  -- For each non responding process retrieve the PID 
            if pid is not "" then do shell script ("kill -9 " & pid) -- KILL the PID. 
        end repeat
    end tell
end tell
Matthieu Riegler
źródło
W wierszu pojawia się błąd kompilacji tell radio button 1 of radio. Usunąłem to i poprawiłem kilka innych rzeczy (chcę tylko zabić określony program) i otrzymałem błąd czasu wykonania: „błąd” Wystąpił błąd w zdarzeniach systemowych: Dostęp dla urządzeń pomocniczych jest wyłączony ”. numer -1719 z okna 1 procesu „Monitor aktywności”
C. Ross
Czy uruchomiłeś ten skrypt w OSX Mavericks?
Matthieu Riegler,
OSX 10.8, więc nie.
C. Ross
pracował nad 10.12.5 po zmianie natell radio button 1 of radio group 1 of group 2 of toolbar 1 of window 1 to click
Charlie Gorichanaz
0

(Opublikowanie tego jako oddzielnej odpowiedzi, ponieważ jest zbyt długie, aby zmieściło się w komentarzu)

Podziękowania dla @MatthieuRiegler za oryginalny skrypt.

Działa to 10.12.6 i jest niewielką modyfikacją oryginalnego skryptu (zobaczyłem komentarz @ CharlieGorichanaz po tym, jak przeprowadziłem własne dochodzenie):


set textToSearchForInProcessName to "Not Responding"

--  Run Activity Monitor 
tell application "Activity Monitor" to activate

tell application "System Events" to tell process "Activity Monitor"
    --  Wait for the Activity Monitor window to open
    repeat until (exists window 1)
        delay 1
    end repeat
    --display notification "Window appeared"

    --  Wait for the Menubar to be present
    repeat until (exists menu 1 of menu bar item "View" of menu bar 1)
        delay 1
    end repeat
    --display notification "Menubar appeared"

    --  Make sure View -> My Processes is selected 
    click menu item "My Processes" of menu 1 of menu bar item "View" of menu bar 1

    --  Click the 'CPU View' button  ( **1 ) 
    click radio button 1 of radio group 1 ¬
        of group 2 of toolbar 1 ¬
        of window 1

    --  Working with the list of processes 
    tell outline 1 of scroll area 1 of window 1
        --  Looking for Not responding process  
        set notResponding to rows whose value of ¬
            first static text contains textToSearchForInProcessName

        repeat with aProcess in notResponding

            --  For each non responding process retrieve the PID 
            set pid to value of text field 1 of aProcess -- ( **2 )

            --  Kill that process using pid 
            if pid is not "" then do shell script ("kill -9 " & pid)
        end repeat
    end tell
end tell

** 1 W systemie macOS 10.12.x pasek narzędzi zawiera dodatkowąwprowadź opis zdjęcia tutajikonę, dzięki którejgroup 2 of toolbar 1zamiastprzycisków znajduje się zestaw przycisków (procesor, pamięć, energia itp.) group 1 of toolbar 1. W przypadku braku tej ikony (nie potwierdziłem tego w starszych wersjach systemu macOS), myślę, że byłyby tam przyciski procesora itpgroup 1 of toolbar 1

** 2 Ma to zastosowanie, jeśli kiedykolwiek przeciągałeś kolumnę PID w kolumnie Aktywność w inne miejsce. Przeciągnąłem kolumnę PID do skrajnej lewej pozycji, więc w tym wierszu musiałem zmienić indeks na1:

set pid to value of text field 1 of aProcess

Kolumny są ponumerowane od lewej strony, zaczynając od 1. W razie potrzeby odpowiednio dostosuj podświetlony indeks w powyższej linii.

Ashutosh Jindal
źródło