Como posso determinar se um aplicativo não está respondendo?

10

Eu tenho um aplicativo no OSX que entra repetidamente em um estado não respondendo e tem que ser forçado a ser morto. Eu estava esperando para automatizá-lo, mas ao inspecionar o processo com ps eu não vejo nada que corresponda com o estado não respondendo. Eu olhei para o indicador state , mas o aplicativo mostra como S se está respondendo ou não.

state The state is given by a sequence of characters, for example, ''RWNA''. The first character indicates the run state of the process:

  • I Marks a process that is idle (sleeping for longer than about 20 seconds).
  • R Marks a runnable process.
  • S Marks a process that is sleeping for less than about 20 seconds.
  • T Marks a stopped process.
  • U Marks a process in uninterruptible wait.
  • Z Marks a dead process (a ''zombie'').

Como posso determinar se o processo está Não respondendo como o Gerenciador de atividades faz?

Estou aberto também às soluções AppleScript.

    
por C. Ross 13.12.2013 / 17:23

3 respostas

8

O estado de Not Responding não é um estado de processo, mas o processo parou de se comunicar com o gerenciador de janelas / mecanismo gráfico. Pode ser amarrado em um loop, pendurado em um soquete, arquivo remoto, qualquer coisa que o mantenha retornando ao loop principal que lida com eventos. O gerenciador de janelas percebe que os eventos estão sendo enfileirados e, portanto, o rotula como "Não está respondendo"

Você pode precisar escrever um pequeno programa X11 que envia eventos fictícios para o processo e, em seguida, eliminá-lo se ele não responder.

    
por 13.12.2013 / 18:19
4

Aqui está um AppleScript usando scripts de interface do usuário que procura um processo que não responde e os mata.

Funcionará com o Activity Monitor of Mavericks. Mas como isso é um script de interface do usuário e como a interface do usuário do Activity Monitor foi alterada, isso provavelmente não funcionará com o OS X mais antigo sem algumas pequenas modificações.

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
    
por 14.12.2013 / 03:15
0

(Postando isso como uma resposta separada desde muito tempo para caber em um comentário)

Agradecemos a @MatthieuRiegler pelo roteiro original.

Isso funcionou em 10.12.6 e é uma pequena modificação do script original (vi o comentário de CharlieGorichanaz depois que eu fiz minha própria investigação):


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 No macOS 10.12.x, a barra de ferramentas contém um ícone devido ao qual o conjunto de botões (CPU, Memória, Energia, etc) está em group 2 of toolbar 1 em vez de group 1 of toolbar 1 . Na ausência desse ícone (eu não confirmei em versões antigas do macOS), acredito que os botões da CPU etc estariam em group 1 of toolbar 1

** 2 Isso se aplica se você já arrastou a coluna PID na coluna Atividade para uma posição diferente. Eu tinha arrastado a coluna PID para a posição mais à esquerda, então nessa linha, eu tive que mudar o índice para 1 :

set pid to value of text field 1 of aProcess

As colunas são numeradas a partir da esquerda, começando em 1. Então, ajuste o índice destacado na linha acima, se necessário.

    
por 12.05.2018 / 19:40