12 votes

Comment puis-je déterminer si une application ne répond pas ?

J'ai une application sous OSX qui se met à plusieurs reprises dans un état de non-réponse et doit être tuée de force. J'espérais pouvoir l'automatiser, mais en inspectant le processus avec la commande ps Je ne vois rien qui corresponde à l'état "Ne répond pas". J'ai regardé le état mais l'application s'affiche comme S qu'il réponde ou non.

state L'état est donné par une séquence de caractères, par exemple, "RWNA". Le premier caractère indique l'état d'exécution du processus :

  • Je marque un processus qui est inactif (dormant pendant plus de 20 secondes environ).
  • R Marque un processus exécutable.
  • S Marque un processus qui est en sommeil pendant moins de 20 secondes environ.
  • T Marque un processus arrêté.
  • U Marque un processus en attente ininterrompue.
  • Z Marque un processus mort (un ``zombie'').

Comment puis-je déterminer si le processus est Ne pas répondre comme le fait le gestionnaire d'activités ?


Je suis également ouvert aux solutions AppleScript.

9voto

JvO Points 893

L'état "Not Responding" n'est pas un état du processus, mais plutôt le processus a cessé de communiquer avec le gestionnaire de fenêtres / moteur graphique. Il peut être bloqué dans une boucle, suspendu à un socket, un fichier distant, n'importe quoi qui l'empêche de revenir à la boucle principale qui gère les événements. Le gestionnaire de fenêtres remarque que les événements sont mis en file d'attente et l'étiquette donc comme "ne répondant pas".

Vous devrez peut-être écrire un petit programme X11 qui envoie des événements fictifs au processus, puis le tuer s'il ne répond pas.

4voto

Allyl Isocyanate Points 321

Voici un AppleScript utilisant le scripting UI qui recherche un processus ne répondant pas et le tue.

Il fonctionnera avec le moniteur d'activité de Mavericks. Mais comme il s'agit d'un script d'interface utilisateur et que l'interface utilisateur d'Activity Monitor a changé, il est fort probable que cela ne fonctionne pas avec les anciens OS X sans quelques modifications mineures.

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

0voto

Ashutosh Jindal Points 661

(Je poste cette réponse séparément car elle est trop longue pour tenir dans un commentaire)

Crédit à @MatthieuRiegler pour le script original.

Cela a fonctionné sous 10.12.6 et est une modification mineure du script original (j'ai vu le commentaire de @CharlieGorichanaz après avoir fait mes propres recherches) :

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 Dans macOS 10.12.x, la barre d'outils contient une fonction supplémentaire enter image description here grâce à laquelle l'ensemble des boutons (CPU, Mémoire, Energie, etc.) sont en cours d'affichage. group 2 of toolbar 1 au lieu de group 1 of toolbar 1 . En l'absence de cette icône (je n'ai pas confirmé dans les versions plus anciennes de macOS), je pense que les boutons CPU etc. seraient en group 1 of toolbar 1

**2 Cela s'applique si vous avez déjà fait glisser la colonne PID dans la colonne Activité vers une position différente. J'avais fait glisser la colonne PID vers la position la plus à gauche, donc sur cette ligne, je devais changer l'index en 1 :

set pid to value of text field 1 of aProcess

Les colonnes sont numérotées de la plus à gauche, en commençant par 1. Ajustez donc l'indice en surbrillance dans la ligne ci-dessus en conséquence si nécessaire.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X