Почему SIGKILL не завершает остановленную программу (да)?

Я не emacs пользователь, но если Вы работаете за пределами среды GUI, можно использовать мышь общего назначения (gpm) демон на Linux и я предположил бы, что некоторый другой *отклоняет. Большинство дистрибутивов имеет его в наличии как пакет, таким образом, все, что необходимо сделать, установить его и запустить сервис.

Можно вырезать и вставить в VC этот путь с мышью (я думаю, что кнопка 1 является выбором, кнопка 2 является вставкой - нет никакого всплывающего меню; это берет немного привыкающее к). Можно, на самом деле, скопировать и вставить через VC. Это работает с комплексом ncurses приложения, сродни emacs, такие как энергия.

8
13.06.2015, 17:17
4 ответа

Сигналы блокируются для приостановленных процессов. В терминале:

$ yes
...
y
y
^Zy

[1]+  Stopped                 yes

Во втором терминале:

$ killall yes

В первом терминале:

$ jobs
[1]+  Stopped                 yes

$ fg
yes
Terminated

Однако SIGKILL не может быть заблокирован. То же самое с killall -9 yes из второй клеммы сразу же дает в клемме yes:

[1]+  Killed                  yes

Следовательно, если kill -9 %1 не завершает процесс сразу, то либо bash на самом деле не посылает сигнал до тех пор, пока вы fg процесса, либо вы не обнаружили ошибку в ядре.

10
27.01.2020, 20:08

Вы наблюдаете ошибку в этой версии бэша.

kill -9 %1 действительно убивает работу немедленно. Вы можете наблюдать это с помощью ps. Вы можете отследить бэш-процесс, чтобы увидеть, когда вызывается системный вызов kill, и отследить подпроцесс, чтобы увидеть, когда он принимает и обрабатывает сигналы. В более интернациональном плане, вы можете пойти и посмотреть, что происходит с процессом.

bash-4.3$ sleep 9999
^Z
[1]+  Stopped                 sleep 9999
bash-4.3$ kill -9 %1

[1]+  Stopped                 sleep 9999
bash-4.3$ jobs
[1]+  Stopped                 sleep 9999
bash-4.3$ jobs -l
[1]+  3083 Stopped                 sleep 9999
bash-4.3$ 

В другом терминале:

% ps 3083
  PID TTY      STAT   TIME COMMAND
 3083 pts/4    Z      0:00 [sleep] <defunct>

Подпроцесс является зомби . Он мертв: от него осталась только запись в таблице процесса (но нет памяти, кода, открытых файлов и т.д.). Запись оставлена до тех пор, пока ее родитель не заметит и не получит статус выхода, вызвав системный вызов wait или одного из своих братьев и сестер.

Интерактивная оболочка должна проверять на наличие мертвых дочерних элементов и пожинать их перед печатью запроса (если не настроено иначе). Эта версия bash не справляется при некоторых обстоятельствах:

bash-4.3$ jobs -l
[1]+  3083 Stopped                 sleep 9999
bash-4.3$ true
bash-4.3$ /bin/true
[1]+  Killed                  sleep 9999

Вы можете ожидать, что bash сообщит "Killed", как только напечатает приглашение после команды kill, но это не гарантируется, потому что есть состояние гонки. Сигналы доставляются асинхронно: системный вызов kill возвращается, как только ядро выяснит, в какой процесс (какие процессы) доставить сигнал, не дожидаясь его фактической доставки. Возможно, и это действительно происходит на практике, что bash успевает проверить состояние своего подпроцесса, обнаружить, что он ещё не мёртв (wait4 не сообщает о смерти ребёнка), и распечатать, что процесс всё ещё останавливается. Ошибкой является то, что перед следующим запросом был получен сигнал (ps сообщает, что процесс мертв), но bash все еще не вызвал wait4 (мы видим это не только потому, что он все еще сообщает задание как "Stopped", но и потому, что зомби все еще присутствует в таблице процесса). На самом деле, bash только пожинает зомби в следующий раз, когда ему нужно будет вызвать wait4, когда он выполнит какую-нибудь другую внешнюю команду.

Баг прерывистый, и я не смог воспроизвести его, пока отслеживается bash (предположительно потому, что это состояние гонки, в котором bash должен реагировать быстро). Если сигнал доставляется до проверки бэша, все происходит так, как и ожидалось.

2
27.01.2020, 20:08

В вашей системе может происходить что-то странное, на мой взгляд, ваш рецепт отлично работает как с -9, так и без него :

> yes
...
^Z
[1]+  Stopped                 yes
> jobs
[1]+  Stopped                 yes
> kill %1
[1]+  Killed                  yes
> jobs
> 

Получите pid с помощью jobs -p и попробуйте чтобы убить его как root .

2
27.01.2020, 20:08

Необходимо иметь источник ядра с включенным взломом ядра. Затем включите CONFIG _ DEBUG _ KMEMLEAK и скомпилируйте ядро.

При выполнении:

echo scan >  /sys/kernel/debug/kmemleak

для включения и

cat /sys/kernel/debug/kmemleak

для отчета.

Исходное предложение рассмотрено на lwn.net

В дереве исходного кода ядра в разделе Документация имеется kmemleak.txt

-121--133287-

Это также можно сделать с помощью правил перезаписи apache для случаев, когда вы не пересылаете tomcat, как описано Ламбертом.

RewriteCond% {HTTP _ HOST} ^ wp.me.com $

RewriteRule ^ (. *) $ http://your.apache.wordpress.com/ $1 [R = 301, L]

-121--100529-

Не паникуйте.

Ничего смешного не происходит. Здесь нет ошибки ядра. Это совершенно нормальное поведение от оболочки Bourne Again и многозадачной операционной системы.

Следует помнить, что процесс убивает себя , даже в ответ на SIGKILL . То, что происходит здесь, это то, что оболочка Bourne Again приходит к вещам , прежде чем процесс, который он только что сказал убить себя, становится убийством самого себя.

Рассмотрим, что происходит из точки, где yes остановлено с помощью SIGTSTP и вы только что выполнили команду kill с помощью оболочки Bourne Again:

  1. оболочка отправляет SIGKILL процессу yes .
  2. Параллельно :
    1. Запланирован запуск процесса yes , который немедленно завершит работу.
    2. Оболочка Bourne Again продолжается, выдавая другую подсказку.

Причина того, что вы видите одну вещь, а другие люди видят другую, заключается в простой гонке между двумя готовыми к запуску процессами, победитель которой полностью зависит от вещей, которые варьируются как от машины к машине, так и с течением времени. Системная нагрузка имеет значение, равно как и тот факт, что ваш ЦП является виртуальным.

В интересном случае детализация шага # 2 такова:

  1. Оболочка Bourne Again продолжается.
  2. В составе внутренних устройств встроенной команды kill помечает запись в своей таблице заданий как требующую сообщения уведомления, напечатанного в следующей доступной точке.
  3. Она завершает выполнение команды kill и непосредственно перед печатью запроса снова проверяет, следует ли печатать уведомления о заданиях.
  4. У процесса да еще не было возможности покончить с собой, так что, если дело касается оболочки, работа все еще находится в остановленном состоянии. Таким образом, оболочка печатает строку состояния задания «Stopped» для этого задания и сбрасывает флаг ожидания уведомления.
  5. Процесс yes запланирован и сам себя убивает.
  6. Ядро сообщает оболочке, которая занята запуском редактора командной строки, что процесс завершил работу. Оболочка отмечает изменение состояния и помечает задание как ожидающее уведомления снова.
  7. Простое нажатие enter для повторного циклического перехода к печати приглашения дает оболочке возможность распечатать новый статус задания.

Важные точки:

  • Процессы убивают себя. SIGKILL не является магическим. Процессы проверяют наличие ожидающих сигналов при возврате в режим приложения из режима ядра, что происходит в конце отказов страницы, (не вложенных) прерываний и системных вызовов. Единственная особенность заключается в том, что ядро не допускает, чтобы действие в ответ на SIGKILL было чем-то иным, кроме немедленного и безусловного самоубийства, без возврата в режим приложения. Важно отметить, что процессы должны одновременно выполнять переходы из ядра в режим приложения и , чтобы реагировать на сигналы.
  • Виртуальный ЦП - это просто поток в операционной системе хоста. Нет гарантии, что узел запланировал запуск виртуального ЦП. Серверные операционные системы тоже не волшебны.
  • Сообщения уведомления не печатаются при изменении состояния задания (если не используется set -o notify ). Они печатаются, когда следующая оболочка достигает точки в своем цикле выполнения, что она проверяет, находятся ли какие-либо уведомления в ожидании.
  • Флаг ожидания уведомления устанавливать дважды, один раз с помощью kill и один раз с помощью обработчика сигналов SIGCHLD . Это означает, что можно увидеть два сообщения, если оболочка выполняется перед процессом yes , перепланированным для самоуничтожения; одно сообщение «Stopped» и одно сообщение «Killed».
  • Очевидно, что программа /bin/kill не имеет доступа к внутренней таблице заданий оболочки; таким образом, вы не увидите такого поведения при /bin/kill . Флаг ожидания уведомления устанавливается обработчиком SIGCHLD только один раз.
  • По той же причине вы не увидите такого поведения, если убьете процесс yes из другой оболочки.
7
27.01.2020, 20:08

Теги

Похожие вопросы