Моя серверная программа получила SIGTERM и остановилась (с кодом выхода 0). Я удивлен этим, поскольку я почти уверен, что для этого было достаточно памяти. При каких условиях linux (busybox) отправляет процесс SIGTERM?
Я не могу вспомнить ни одного случая, когда ядро или стандартный инструмент отправляли бы SIGTERM в случайный процесс. Что вы можете рассказать нам о том, что делает программа и как она запускается? Как вы узнали о статусе выхода из программы? Можете ли вы воспроизвести проблему? У вас есть журналы, которые вы можете проверить?
Жиль "ТАК - перестань быть злым"
Он читает и записывает в последовательную линию и отвечает на запросы UDP и TCP. Я завернул выполнение сценария bash и поэтому знаю код выхода.
michelemarcon
1
Документация Posix указывает, что SIGTERM является событием исключительно пользовательского уровня. Возможно ли, что кто-то еще смог убить вашу серверную программу?
shellter
3
Ты! Код возврата 0 означает нормальный выход. Если бы был SIGTERM, $?было бы установлено значение 143 (128 + номер сигнала).
Жиль "ТАК - перестань быть злым"
1
Кроме того, ^ C - это SIGINT, а не SIGTERM, и это завершится с кодом 130.
flarn2006
Ответы:
13
Я опубликую это как ответ, чтобы было какое-то решение, если это окажется проблемой.
Статус выхода 0 означает нормальный выход из успешной программы. Выход из программы можно выбрать любое целое число от 0 до 255 , как его статус выхода. Традиционно программы используют небольшие значения. Значения 126 и выше используются оболочкой для сообщения об особых условиях, поэтому лучше их избегать.
На уровне C API программы сообщают о 16-битном состоянии, которое кодирует как состояние выхода из программы, так и сигнал, который ее убил, если таковой имеется.
В оболочке статус завершения команды (сохраненный в $?) связывает фактическое состояние выхода программы и значение сигнала: если программа прерывается сигналом, $?устанавливается значение больше 128 (для большинства оболочек это значение равно 128 плюс номер сигнала; ATT ksh использует 256 + номер сигнала, а yash использует 384 + номер сигнала, что позволяет избежать неоднозначности, но другие оболочки не следуют этому примеру).
В частности, если $?0, ваша программа вышла нормально.
Обратите внимание, что это относится к случаю процесса, который получает SIGTERM, но имеет для него обработчик сигнала и в конечном итоге завершает работу нормально (возможно, как косвенное следствие сигнала SIGTERM, возможно, нет).
Чтобы ответить на вопрос в вашем заголовке, система никогда не отправляет SIGTERM автоматически. Есть несколько сигналов, которые отправляются автоматически, например, SIGHUP, когда терминал отключается, SIGSEGV / SIGBUS / SIGILL, когда процесс делает то, что он не должен делать, SIGPIPE, когда он пишет в сломанный канал / сокет, и т. Д. несколько сигналов, которые отправляются из-за нажатия клавиши в терминале, в основном SIGINT для Ctrl+ C, SIGQUIT для Ctrl+ \и SIGTSTP для Ctrl+ Z, но SIGTERM не является одним из них. Если процесс получает SIGTERM, какой-то другой процесс отправил этот сигнал.
Хорошее объяснение того, как статус выхода определяется при получении сигнала. Однако этот ответ не касается вопроса ОП.
codeforester
1
@codeforester Я ответил на вопрос в теле, а не на вопрос в заголовке. Ну, один из вопросов в теле - учитывая, что оно основано на недоразумении, это немного грязно. Я добавлю пару слов об отдыхе.
Жиль "ТАК - перестань быть злым"
Это зависит от оболочки. В ksh93 это 256 + signum, в yash - 384 + signum
Стефан
Обратите внимание, что использование значения выше 256 a la ksh не обязательно лучше, так как это предотвращает его передачу exit. yashПодход является хорошим компромиссом, но видеть гс для другого. См. Также Код завершения по умолчанию, когда процесс завершается?
Стефан
10
SIGTERM - это сигнал, который обычно используется для административного завершения процесса.
Это не сигнал, который отправляет ядро, но сигнал, который процесс обычно посылает для завершения (изящно) другого процесса.
Это сигнал, который отправляется по умолчанию kill , pkill, killall, fuser -k... команд.
Это сигнал, который посылается демонам, чтобы остановить их (как при a service some-service stop), или initперед передачей (после SIGKILL для тех процессов, которые не успели завершиться вовремя после SIGTERM).
Обратите внимание, что SIGTERM не является сигналом, который отправляется ^C. Сигнал отправляется ^CSIGINT.
$?
было бы установлено значение 143 (128 + номер сигнала).Ответы:
Я опубликую это как ответ, чтобы было какое-то решение, если это окажется проблемой.
Статус выхода 0 означает нормальный выход из успешной программы. Выход из программы можно выбрать любое целое число от 0 до 255 , как его статус выхода. Традиционно программы используют небольшие значения. Значения 126 и выше используются оболочкой для сообщения об особых условиях, поэтому лучше их избегать.
На уровне C API программы сообщают о 16-битном состоянии, которое кодирует как состояние выхода из программы, так и сигнал, который ее убил, если таковой имеется.
В оболочке статус завершения команды (сохраненный в
$?
) связывает фактическое состояние выхода программы и значение сигнала: если программа прерывается сигналом,$?
устанавливается значение больше 128 (для большинства оболочек это значение равно 128 плюс номер сигнала; ATT ksh использует 256 + номер сигнала, а yash использует 384 + номер сигнала, что позволяет избежать неоднозначности, но другие оболочки не следуют этому примеру).В частности, если
$?
0, ваша программа вышла нормально.Обратите внимание, что это относится к случаю процесса, который получает SIGTERM, но имеет для него обработчик сигнала и в конечном итоге завершает работу нормально (возможно, как косвенное следствие сигнала SIGTERM, возможно, нет).
Чтобы ответить на вопрос в вашем заголовке, система никогда не отправляет SIGTERM автоматически. Есть несколько сигналов, которые отправляются автоматически, например, SIGHUP, когда терминал отключается, SIGSEGV / SIGBUS / SIGILL, когда процесс делает то, что он не должен делать, SIGPIPE, когда он пишет в сломанный канал / сокет, и т. Д. несколько сигналов, которые отправляются из-за нажатия клавиши в терминале, в основном SIGINT для Ctrl+ C, SIGQUIT для Ctrl+ \и SIGTSTP для Ctrl+ Z, но SIGTERM не является одним из них. Если процесс получает SIGTERM, какой-то другой процесс отправил этот сигнал.
¹ грубо говоря
источник
exit
.yash
Подход является хорошим компромиссом, но видеть гс для другого. См. Также Код завершения по умолчанию, когда процесс завершается?SIGTERM - это сигнал, который обычно используется для административного завершения процесса.
Это не сигнал, который отправляет ядро, но сигнал, который процесс обычно посылает для завершения (изящно) другого процесса.
Это сигнал, который отправляется по умолчанию
kill
,pkill
,killall
,fuser -k
... команд.Это сигнал, который посылается демонам, чтобы остановить их (как при a
service some-service stop
), илиinit
перед передачей (после SIGKILL для тех процессов, которые не успели завершиться вовремя после SIGTERM).Обратите внимание, что SIGTERM не является сигналом, который отправляется
^C
. Сигнал отправляется^C
SIGINT.источник