Коли система надсилає SIGTERM до процесу?


24

Моя серверна програма отримала SIGTERM і зупинилася (з кодом виходу 0). Я здивований цим, оскільки я майже впевнений, що на це було достатньо пам’яті. За яких умов linux (busybox) надсилає SIGTERM до процесу?


Я не можу придумати жоден випадок, коли ядро ​​або стандартний інструмент посилає SIGTERM до випадкового процесу. Що ви можете сказати нам про те, що робить програма і як вона запускається? Як ви дізналися про статус виходу з програми? Чи можете ви відтворити проблему? Чи є у вас журнали, які ви можете перевірити?
Жил "ТАК - перестань бути злим"

Він читає та записує до послідовного рядка та відповідає на запити UDP та TCP. Я завернув виконання на скрипт bash, і тому знаю вихідний код.
michelemarcon

1
Документація Posix вказує, що SIGTERM є суто подією на рівні користувача. Чи можливо хтось інший зміг вбити вашу серверну програму?
обстріл

3
Ти є! Код повернення 0 означає нормальний вихід. Якщо був SIGTERM, $?було б встановлено 143 (128 + номер сигналу).
Жил "ТАК - перестань бути злим"

1
Крім того, ^ C є SIGINT, а не SIGTERM, і це може вийти з кодом 130.
flarn2006

Відповіді:


13

Я опублікую це як відповідь, щоб було якесь рішення, якщо це виявиться проблемою.

Статус виходу 0 означає нормальний вихід із успішної програми. Вихідна програма може вибрати будь-яке ціле число між 0 і 255 як свій статус виходу. Зазвичай програми використовують малі значення. Значення 126 і вище використовуються оболонкою для повідомлення про особливі умови, тому краще уникати їх.

На рівні API 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 + сигнум, у яші - це 384 +
синум

Зауважте, що використання значення вище 256 a la ksh не обов'язково краще, оскільки це перешкоджає його передачі exit. yashПідхід є хорошим компромісом, але бачити гс для іншого. Дивіться також код виходу за замовчуванням, коли процес закінчується?
Стефан Шазелас

10

SIGTERM - це сигнал, який зазвичай використовується для адміністративного завершення процесу.

Це не сигнал, який ядро ​​надсилатиме, але це сигнал, який звичайно процес надсилає для завершення (витончено) іншого процесу.

Це сигнал , який надсилається за замовчуванням з допомогою kill, pkill, killall, fuser -k... команд.

Це сигнал, який надсилається демонам, щоб зупинити їх (як на a service some-service stop), або посилається initперед вимкненням (слідом за цим SIGKILL для тих процесів, які не встигли закінчитися в SIGTERM).

Зауважте, що SIGTERM - це не сигнал, який надсилається ^C. Сигнал, що надсилається, ^Cє SIGINT.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.