Как я могу определить, что приложение не отвечает?

11

У меня есть приложение на OSX, которое постоянно переходит в состояние «Не отвечает» и должно быть принудительно уничтожено. Я надеялся автоматизировать его, но при проверке процесса с помощью ps я не вижу ничего, что соответствовало бы состоянию Not Responding. Я посмотрел на индикатор состояния , но приложение показывает как S , отвечает ли он или нет.

состояние Состояние задается последовательностью символов, например, `` RWNA ''. Первый символ указывает на состояние выполнения процесса:

  • I Отмечает процесс, который простаивает (спит дольше, чем около 20 секунд).
  • R отмечает исполняемый процесс.
  • S Отмечает процесс, который спит менее 20 секунд.
  • T отмечает остановленный процесс.
  • U отмечает процесс в непрерывном ожидании.
  • Z отмечает мертвый процесс ("зомби").

Как определить, не отвечает ли процесс, как это делает Менеджер активности?


Я также открыт для решений AppleScript.

Пересекать
источник

Ответы:

9

Состояние Not Responding - это не состояние процесса, а процесс прекратил связь с оконным менеджером / графическим ядром. Это может быть связано в цикле, висящем на сокете, удаленном файле, чем угодно, что заставляет его возвращаться в основной цикл, который обрабатывает события. Диспетчер окон замечает, что события находятся в очереди, и поэтому помечает его как «Не отвечающий».

Вам может потребоваться написать небольшую программу X11, которая отправляет фиктивные события процессу, а затем убить ее, если она не отвечает.

JvO
источник
Может быть, написать что-то с AppleScript, что в качестве уровня доступа пользовательского интерфейса.
Матье Риглер,
@MatthieuRiegler Как бы вы сделали это в AppleScript?
К. Росс
Я привел пример в другом ответе.
Матье Риглер,
4

Вот AppleScript, использующий сценарии пользовательского интерфейса, который ищет не отвечающий процесс и убивает их.

Он будет работать с монитором активности Mavericks. Но так как это сценарии пользовательского интерфейса и пользовательский интерфейс Activity Monitor изменился, он, скорее всего, не будет работать со старой OS X без каких-либо незначительных изменений.

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
Мэтью Риглер
источник
Я получаю ошибку компиляции в строке tell radio button 1 of radio. Я удалил это и настроил некоторые другие вещи (я только хочу убить определенную программу) и получил ошибку времени выполнения: 'ошибка' Системные события получили ошибку: доступ для вспомогательных устройств отключен. " номер -1719 из окна 1 процесса «Монитор активности» '
К. Росс
Этот скрипт запускался на OSX Mavericks?
Матье Риглер,
OSX 10.8, так что нет.
К. Росс
работал 10.12.5 после смены наtell radio button 1 of radio group 1 of group 2 of toolbar 1 of window 1 to click
Чарли
0

(Размещать это как отдельный ответ, так как слишком долго, чтобы уместиться в комментарии)

Благодарим @MatthieuRiegler за оригинальный сценарий.

Это сработало 10.12.6 и является незначительной модификацией оригинального сценария (см. Комментарий @ CharlieGorichanaz после того, как я провел собственное расследование):


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 В macOS 10.12.x панель инструментов содержит дополнительныйвведите описание изображения здесьзначок, благодаря которомуgroup 2 of toolbar 1вместокнопок используется набор кнопок (CPU, Memory, Energy и т. Д.) group 1 of toolbar 1. В отсутствие этого значка (я не подтвердил в старых версиях macOS), я думаю, что кнопки CPU и т. Д.group 1 of toolbar 1

** 2 Это применимо, если вы когда-либо перетаскивали столбец PID в столбце Activity в другую позицию. Я перетащил столбец PID в крайнее левое положение, поэтому в этой строке мне пришлось изменить индекс на1:

set pid to value of text field 1 of aProcess

Столбцы пронумерованы слева, начиная с 1. Поэтому при необходимости измените подсвеченный индекс в строке выше.

Ашутош Джиндал
источник