Quando o sistema envia um SIGTERM para um processo?

24

Meu programa servidor recebeu um SIGTERM e parou (com o código de saída 0). Estou surpreso com isso, pois tenho certeza de que havia muita memória para isso. Sob quais condições o linux (busybox) envia um SIGTERM para um processo?

michelemarcon
fonte
Não consigo pensar em nenhum caso em que o kernel ou uma ferramenta padrão envie o SIGTERM para um processo aleatório. O que você pode nos dizer sobre o que o programa está fazendo e como é iniciado? Como você descobriu o status de saída do programa? É possível reproduzir o problema? Você tem logs que você pode verificar?
Gilles 'SO- stop be evil' (
Ele está lendo e gravando em uma linha serial e está respondendo a solicitações UDP e TCP. Eu envolvi a execução em um script bash e, portanto, conheço o código de saída.
Michelemarcon
1
A documentação do Posix indica que o SIGTERM é estritamente um evento no nível do usuário. É possível que outra pessoa tenha conseguido matar o seu programa de servidor?
shellter 29/03
3
Tu es! O código de retorno 0 significa uma saída normal. Se houvesse um SIGTERM, $?seria definido como 143 (128 + número do sinal).
Gilles 'SO- stop be evil'
1
Além disso, ^ C é SIGINT, não SIGTERM, e que iria sair com um código de 130.
flarn2006

Respostas:

13

Vou postar isso como resposta, para que haja algum tipo de resolução, se esse for o problema.

Um status de saída 0 significa uma saída normal de um programa bem-sucedido. Um programa existente pode escolher qualquer número inteiro entre 0 e 255 como status de saída. Convencionalmente, os programas usam valores pequenos. Os valores 126 e acima são usados ​​pelo shell para relatar condições especiais; portanto, é melhor evitá-las.

No nível da API C, os programas relatam um status de 16 bits¹ que codifica o status de saída do programa e o sinal que o interrompeu , se houver.

No shell, o status de saída de um comando (salvo em $?) conflita o status de saída real do programa e o valor do sinal: se um programa é morto por um sinal, $?é definido como um valor maior que 128 (com a maioria dos shells, esse valor é 128 mais o número do sinal; ATT ksh usa 256 + número de sinal e yash usa 384 + número de sinal, o que evita a ambiguidade, mas as outras conchas não seguiram o exemplo).

Em particular, se $?for 0, seu programa saiu normalmente.

Observe que isso inclui o caso de um processo que recebe o SIGTERM, mas possui um manipulador de sinal e, eventualmente, sai normalmente (talvez como uma conseqüência indireta do sinal do SIGTERM, talvez não).


Para responder à pergunta em seu título, o SIGTERM nunca é enviado automaticamente pelo sistema. Existem alguns sinais que são enviados automaticamente como SIGHUP quando um terminal sai, SIGSEGV / SIGBUS / SIGILL quando um processo faz coisas que não deveriam estar fazendo, SIGPIPE quando grava em um tubo / soquete quebrado etc. alguns sinais enviados devido ao pressionamento de tecla em um terminal, principalmente SIGINT para Ctrl+ C, SIGQUIT para Ctrl+ \e SIGTSTP para Ctrl+ Z, mas o SIGTERM não é um deles. Se um processo recebe o SIGTERM, algum outro processo envia esse sinal.

¹ grosso modo

Gilles 'SO- parar de ser mau'
fonte
Boa explicação de como o status de saída é determinado ao receber um sinal. No entanto, esta resposta não aborda a questão do OP.
Codeforester 23/05
1
@ codeforester Eu respondi a pergunta no corpo, não a pergunta no título. Bem, uma das perguntas do corpo - dado que foi baseado em um mal-entendido, é um pouco confuso. Vou adicionar algumas palavras sobre o resto.
Gilles 'SO- stop be evil'
Isso depende da casca. No ksh93, é 256 + signum, em yash, é 384 + signum
Stéphane Chazelas
Observe que o uso de um valor acima de 256 a la ksh não é necessariamente melhor, pois isso impede que ele seja passado para exit. A yashabordagem é um bom compromisso, mas veja rc por outro. Consulte também Código de saída padrão quando o processo é finalizado?
Stéphane Chazelas
10

SIGTERM é o sinal normalmente usado para finalizar administrativamente um processo.

Esse não é um sinal que o kernel enviaria, mas é o sinal que um processo normalmente enviaria para finalizar (normalmente) outro processo.

Esse é o sinal que é enviado por padrão pelos kill, pkill, killall, fuser -k... comandos.

Esse é o sinal enviado aos daemons para interrompê-los (como no a service some-service stop) ou enviado initantes do desligamento (seguido pelo SIGKILL para os processos que não conseguiram terminar a tempo no SIGTERM).

Observe que SIGTERM não é o sinal enviado ^C. O sinal enviado ^Cé SIGINT.

Stéphane Chazelas
fonte