시스템은 언제 프로세스에 SIGTERM을 보냅니 까?


24

내 서버 프로그램이 SIGTERM을 수신하고 종료했습니다 (종료 코드 0). 메모리가 충분하다는 것을 확신하기 때문에 이것에 놀랐습니다. Linux (busybox)는 어떤 조건에서 SIGTERM을 프로세스에 전송합니까?


커널이나 표준 도구가 SIGTERM을 임의의 프로세스로 보내는 경우를 생각할 수 없습니다. 프로그램이 수행하는 작업과 시작 방법에 대해 무엇을 알려줄 수 있습니까? 프로그램의 종료 상태를 어떻게 알았습니까? 문제를 재현 할 수 있습니까? 확인할 수있는 로그가 있습니까?
Gilles 'SO- 악한 중지'

직렬 회선을 읽고 쓰고 있으며 UDP 및 TCP 요청에 응답하고 있습니다. bash 스크립트에서 실행을 래핑 했으므로 종료 코드를 알고 있습니다.
michelemarcon

1
Posix 설명서는 SIGTERM이 엄격하게 사용자 수준의 이벤트임을 나타냅니다. 다른 사람이 서버 프로그램을 죽일 수 있었습니까?
shellter

3
너는! 리턴 코드 0은 정상 종료를 의미합니다. SIGTERM이있는 경우 $?143 (128 + 신호 번호)으로 설정됩니다.
Gilles 'SO- 악의를 멈춰라'

1
또한 ^ C는 SIGTERM이 아닌 SIGINT이며 코드 130으로 종료됩니다.
flarn2006

답변:


13

이것이 문제로 판명되면 어떤 종류의 해결책이 있도록 답변으로 게시 할 것입니다.

종료 상태가 0이면 프로그램이 정상적으로 종료 된 것입니다. 종료 프로그램은 종료 상태로 0과 255 사이의 정수를 선택할 수 있습니다. 일반적으로 프로그램은 작은 값을 사용합니다. 쉘은 126 이상의 값을 사용하여 특수 조건을보고하므로이를 피하는 것이 가장 좋습니다.

C API 레벨에서 프로그램 은 프로그램의 종료 상태와 종료 된 신호가있는 경우이를 모두 암호화 하는 16 비트 상태 ¹보고 합니다.

쉘에서는, 명령의 종료 상태 (저장은 $?) 프로그램의 실제 종료 상태와 신호 값을 conflates : 프로그램이 신호에 의해 살해되는 경우, $?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을 수신하면 다른 프로세스가 해당 신호를 보냈습니다.

대략 ¹


신호 수신시 종료 상태를 결정하는 방법에 대한 설명 그러나이 답변은 OP의 질문을 다루지 않습니다.
codeforester

1
@codeforester 제목의 질문이 아니라 본문의 질문에 대답했습니다. 글쎄, 신체의 질문 중 하나는 오해에 근거한 것이므로 약간 지저분합니다. 나머지 부분에 대해 몇 마디 추가하겠습니다.
Gilles 'SO- 악마 그만해'

그것은 껍질에 달려 있습니다. ksh93에서는 256 + signum, yash에서는 384 + signum입니다
Stéphane Chazelas

256보다 큰 값을 사용하면이 값이로 전달되는 것을 막을 수 있으므로 반드시 더 좋은 것은 아닙니다 exit. 이 yash접근법은 좋은 타협이지만 다른 접근법에 대해서는 rc를 참조하십시오. 프로세스가 종료 될 때 기본 종료 코드를
Stéphane Chazelas

10

SIGTERM은 일반적으로 프로세스를 관리적으로 종료하는 데 사용되는 신호입니다.

이것은 커널이 보내는 신호가 아니라 프로세스가 일반적으로 다른 프로세스를 종료하기 위해 보내는 신호입니다.

즉,에서 기본적으로 전송되는 신호의 kill, pkill, killall, fuser -k... 명령.

이는 데몬에게 중지하기 위해 데몬에 service some-service stop전송되거나 ()와 같이 init종료되기 전에 전송되는 신호입니다 (SIGTERM에서 제 시간에 종료되지 않은 프로세스에 대해서는 SIGKILL이 뒤 따름).

SIGTERM 은 전송되는 신호 가 아닙니다^C . 전송 된 신호 ^C는 SIGINT입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.