Kiedy system wysyła SIGTERM do procesu?


24

Mój program serwera otrzymał SIGTERM i zatrzymał się (z kodem wyjścia 0). Jestem tym zaskoczony, ponieważ jestem całkiem pewien, że było na to mnóstwo pamięci. W jakich warunkach linux (busybox) wysyła SIGTERM do procesu?


Nie mogę wymyślić żadnego przypadku, gdy jądro lub standardowe narzędzie wysłałoby SIGTERM do losowego procesu. Co możesz nam powiedzieć o tym, co robi program i jak się zaczął? Jak dowiedziałeś się o statusie zakończenia programu? Czy potrafisz odtworzyć problem? Czy masz dzienniki, które możesz sprawdzić?
Gilles „SO- przestań być zły”

Odczytuje i zapisuje na linii szeregowej i odpowiada na żądania UDP i TCP. Wykonałem skrypt na skrypcie bash i dlatego znam kod wyjścia.
michelemarcon

1
Dokumentacja Posix wskazuje, że SIGTERM jest zdarzeniem ściśle na poziomie użytkownika. Czy to możliwe, że ktoś inny mógł zabić Twój program serwera?
shellter

3
Ty jesteś! Kod powrotu 0 oznacza normalne wyjście. Gdyby istniał SIGTERM, $?byłby ustawiony na 143 (128 + numer sygnału).
Gilles „SO- przestań być zły”

1
Ponadto ^ C to SIGINT, a nie SIGTERM, i to kończy się kodem 130.
flarn2006

Odpowiedzi:


13

Prześlę to jako odpowiedź, aby istniało jakieś rozwiązanie, jeśli okaże się, że to jest problem.

Status wyjścia 0 oznacza normalne wyjście z udanego programu. Program wychodzenia można wybrać dowolną liczbę całkowitą z przedziału od 0 do 255, jak jej status wyjścia. Konwencjonalnie programy używają małych wartości. Powłoki używają wartości 126 i wyższych do zgłaszania specjalnych warunków, więc najlepiej ich unikać.

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

W powłoce status wyjścia komendy (zapisany w $?) łączy rzeczywisty status wyjścia programu z wartością sygnału: jeśli program zostanie zabity przez sygnał, $?zostanie ustawiony na wartość większą niż 128 (w przypadku większości powłok wartość ta jest równa 128 plus numer sygnału; ATT ksh używa numeru sygnału 256+, a yash używa numeru sygnału 384 +, co pozwala uniknąć dwuznaczności, ale inne powłoki nie poszły tą samą drogą.

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

Należy zauważyć, że dotyczy to przypadku procesu, który odbiera SIGTERM, ale ma dla niego procedurę obsługi sygnału i ostatecznie kończy normalnie (być może jako pośrednią konsekwencję sygnału SIGTERM, a może nie).


Aby odpowiedzieć na pytanie w twoim tytule, SIGTERM nigdy nie jest wysyłany automatycznie przez system. Istnieje kilka sygnałów wysyłanych automatycznie, takich jak SIGHUP, gdy terminal znika, SIGSEGV / SIGBUS / SIGILL, gdy proces wykonuje czynności, których nie powinien robić, SIGPIPE, gdy zapisuje do uszkodzonej rury / gniazda itp. I są kilka sygnałów wysyłanych z powodu naciśnięcia 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, jakiś inny proces wysłał ten sygnał.

¹ z grubsza mówiąc


Dobre wyjaśnienie, w jaki sposób określa się status wyjścia po otrzymaniu sygnału. Jednak ta odpowiedź nie odnosi się do pytania OP.
codeforester

1
@codeforester Odpowiedziałem na pytanie w ciele, a nie na pytanie w tytule. Cóż, jedno z pytań w ciele - biorąc pod uwagę, że było oparte na nieporozumieniu, jest trochę niechlujne. Dodam kilka słów o reszcie.
Gilles „SO- przestań być zły”

To zależy od powłoki. W ksh93 to 256 + signum, w yash to 384 + signum
Stéphane Chazelas

Zauważ, że użycie wartości powyżej 256 a la ksh niekoniecznie jest lepsze, ponieważ zapobiega to jej przekazaniu exit. yashPodejście jest dobrym kompromisem, ale zobacz rc na inną. Zobacz także Domyślny kod wyjścia po zakończeniu procesu?
Stéphane Chazelas

10

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

To nie jest sygnał wysyłany przez jądro, ale to sygnał, który proces zwykle wysyła, aby zakończyć (z wdziękiem) inny proces.

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

Jest to sygnał wysyłany do demonów w celu ich zatrzymania (jak w przypadku a service some-service stop) lub wysyłany initprzed zamknięciem (po którym następuje SIGKILL dla procesów, które nie zakończyły się w czasie po SIGTERM).

Zauważ, że SIGTERM nie jest sygnałem, który jest wysyłany ^C. Wysłany sygnał ^Cto SIGINT.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.