Kiedy system wysyła SIGTERM do procesu?

Mój program serwera odebrał SIGTERM i zatrzymał się (z kodem zakończenia 0). Dziwię się tym, bo jestem prawie pewien, że było na to dużo pamięci. W jakich warunkach linux (busybox) wysyła SIGTERM do procesu?

Komentarze

  • Mogę ' nie myśl o żadnym przypadku, w którym jądro lub standardowe narzędzie wysłałoby SIGTERM do losowego procesu. Co możesz nam powiedzieć o tym, co robi ten program i jak się ' rozpoczął? W jaki sposób dowiedziałeś się o statusie wyjścia ' programu? Czy możesz odtworzyć problem? Czy masz dzienniki, które możesz sprawdzić?
  • Odczytuje i zapisuje na linii szeregowej oraz odpowiada na żądania UDP i TCP. Zapakowałem wykonanie na skrypcie bash i dlatego znam kod zakończenia.
  • Dokumentacja Posix wskazuje, że SIGTERM jest zdarzeniem ściśle na poziomie użytkownika. Czy to możliwe, że ktoś inny był w stanie zabić Twój program serwera?
  • Jesteś! Kod powrotu 0 oznacza normalne wyjście. Gdyby istniał SIGTERM, $? zostałby ustawiony na 143 (128 + numer sygnału).
  • Ponadto ^ C to SIGINT, a nie SIGTERM, i to zakończ z kodem 130.

Odpowiedz

Opublikuję to jako odpowiedź, więc że istnieje jakieś rozwiązanie, jeśli okaże się, że to jest problem.

Kod zakończenia równy 0 oznacza normalne wyjście z pomyślnie zakończonego programu. program wychodzący może wybrać dowolną liczbę całkowitą od 0 do 255 jako swój kod zakończenia. Zwykle programy używają małych wartości. Wartości 126 i wyższe są używane przez powłokę do zgłaszania specjalnych warunków, więc najlepiej ich unikać.

Na poziomie C API programy raportują 16-bitowy status¹ , który koduje zarówno status wyjścia programu, jak i sygnał, który go zabił, jeśli taki istnieje.

W powłoce a polecenie „s status wyjścia (zapisane w $?) łączy rzeczywisty status wyjścia programu z wartością sygnału: jeśli program zostanie zabity przez sygnał, $? jest ustawione na wartość większą niż 128 (w większości powłok ta wartość to 128 plus numer sygnału; ATT ksh używa 256 + numer sygnału, a yash używa 384 + numer sygnału, co pozwala uniknąć niejednoznaczność, ale inne powłoki nie poszły w ich ślady).

W szczególności, jeśli $? wynosi 0, program zakończył normalnie.

Zauważ, że obejmuje to przypadek procesu, który odbiera SIGTERM, ale ma dla niego obsługę sygnału i ostatecznie kończy normalnie (być może jako pośrednia konsekwencja sygnału SIGTERM, być może nie).


Aby odpowiedzieć na pytanie w twoim tytule, SIGTERM nigdy nie jest wysyłany automatycznie przez system. Jest kilka sygnałów, które są wysyłane automatycznie, jak SIGHUP, gdy terminal znika, SIGSEGV / SIGBUS / SIGILL, gdy proces robi rzeczy, których nie powinien robić, SIGPIPE, gdy zapisuje do zepsutej rury / gniazda, itp. kilka sygnałów wysyłanych po naciśnięciu klawisza w terminalu, głównie SIGINT dla Ctrl + C , SIGQUIT dla Ctrl + \ i SIGTSTP dla Ctrl + Z , ale SIGTERM nie jest jednym z nich. Jeśli proces odbiera SIGTERM, inny proces wysłał ten sygnał.

¹ z grubsza

Komentarze

  • Ładne wyjaśnienie, w jaki sposób określa się stan wyjścia po otrzymaniu sygnału. Jednak ta odpowiedź nie ' nie odpowiada pytaniu OP '.
  • @codeforester Odpowiedziałem na pytanie w body, a nie pytanie w tytule. Cóż, jedno z pytań w treści – biorąc pod uwagę, że było oparte na nieporozumieniu, jest trochę bałaganiarskie. I ' Dodam jeszcze kilka słów o reszcie.
  • To zależy od powłoki. W ksh93 to ' s 256 + signum, w yash to ' s 384 + signum
  • Zwróć uwagę, że użycie wartości powyżej 256 a la ksh niekoniecznie jest lepsze, ponieważ zapobiega przekazaniu jej do exit. Podejście yash to dobry kompromis, ale poszukaj innego rozwiązania w rc. Zobacz także Domyślny kod zakończenia po zakończeniu procesu?

Odpowiedź

SIGTERM jest sygnałem, który jest zwykle używany do administracyjnego zakończenia procesu.

To nie jest sygnał, który jądro wyśle, ale to jest sygnał, który proces zazwyczaj wysłać, aby zakończyć (wdzięcznie) inny proces.

To jest sygnał, który jest wysyłany domyślnie przez kill, pkill, killall … polecenia.

To jest sygnał, który jest wysyłany do demonów w celu ich zatrzymania (np. service some-service stop) lub wysyłany przez init przed zamknięciem (po którym następuje SIGKILL dla tych procesów, którym nie udało się zakończyć na czas po SIGTERM).

Zauważ, że SIGTERM nie jest sygnałem wysyłanym po ^C. Sygnał wysłany na ^C to SIGINT.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *