Quando o sistema envia um SIGTERM para um processo?

Meu programa servidor recebeu um SIGTERM e parou (com 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?

Comentários

  • Eu posso ' t pense em qualquer caso em que o kernel ou uma ferramenta padrão enviaria SIGTERM para um processo aleatório. O que você pode nos dizer sobre o que o programa está fazendo e como ' foi iniciado? Como você descobriu o status de saída do programa ' s? É possível reproduzir o problema? Você tem logs para verificar?
  • 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.
  • A documentação do Posix indica que o SIGTERM é estritamente um evento de nível de usuário. É possível que outra pessoa tenha conseguido matar o seu programa de servidor?
  • Você conseguiu! O código de retorno 0 significa uma saída normal. Se houvesse um SIGTERM, $? seria definido como 143 (128 + número do sinal).
  • Além disso, ^ C é SIGINT, não SIGTERM, e isso seria saia com um código de 130.

Resposta

Vou postar isso como uma resposta, que há 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 de saída pode escolher qualquer número inteiro entre 0 e 255 como seu 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á-los.

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 matou, se houver.

No shell, um o status de saída do comando (salvo em $?) combina o status de saída real do programa e o valor do sinal: se um programa for morto por um sinal, $? é definido com um valor maior que 128 (com a maioria dos shells, este valor é 128 mais o número do sinal; ATT ksh usa 256 + número do sinal e yash usa 384 + número do sinal, o que evita a ambigüidade, mas os outros shells “t seguiram o exemplo).

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

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


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

¹ grosso modo

Comentários

  • Bela explicação de como o status de saída é determinado ao receber um sinal. No entanto, esta resposta não ' t responde à pergunta da OP '.
  • @codeforester Respondi à pergunta no corpo, não a pergunta do título. Bem, uma das perguntas do corpo – visto que foi baseada em um mal-entendido, é um pouco confuso. 283285e594 “>

Vou acrescentar algumas palavras sobre o resto.

  • Isso depende do shell. Em ksh93, é ' s 256 + signum, em yash, é ' s 384 + signum
  • Observe que usar um valor acima de 256 a la ksh não é necessariamente melhor, pois evita que ele seja passado para exit. A abordagem yash é um bom compromisso, mas consulte rc para obter outro. Veja também Código de saída padrão quando o processo é encerrado?
  • Resposta

    SIGTERM é o sinal que normalmente é usado para encerrar administrativamente um processo.

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

    Esse é o sinal que é enviado por padrão pelo kill, pkill, killall … comandos.

    Esse é o sinal enviado aos daemons para pará-los (como em um service some-service stop) ou enviado por init antes do desligamento (seguido por SIGKILL para aqueles processos que não conseguiram terminar a tempo após SIGTERM).

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

    Deixe uma resposta

    O seu endereço de email não será publicado. Campos obrigatórios marcados com *