Às vezes fico um pouco confuso com todos os sinais que um processo pode receber. Pelo que entendi, um processo tem um manipulador padrão ( disposição do sinal ) para cada um desses sinais, mas pode fornecer seu próprio manipulador chamando sigaction()
.
Então, aqui está a minha pergunta: o que faz com que cada um dos sinais seja enviado? Sei que você pode enviar sinais manualmente para os processos em execução através do -s
parâmetro kill
, mas quais são as circunstâncias naturais sob as quais esses sinais são enviados? Por exemplo, quando é SIGINT
enviado?
Além disso, existem restrições sobre quais sinais podem ser manipulados? Até SIGSEGV
sinais podem ser processados e o controle retornado ao aplicativo?
Respostas:
Além da chamada de processos
kill(2)
, alguns sinais são enviados pelo kernel (ou algumas vezes pelo próprio processo) em várias circunstâncias:SIGINT
(volte ao loop principal) no Ctrl+ C,SIGQUIT
(saia imediatamente) no Ctrl+ \,SIGTSTP
(suspenda) no Ctrl+ Z. As chaves podem ser alteradas com ostty
comandoSIGTTIN
eSIGTTOU
são enviados quando um processo em segundo plano tenta ler ou gravar em seu terminal de controle.SIGWINCH
é enviado para sinalizar que o tamanho da janela do terminal mudou.SIGHUP
é enviado para o sinal de que o terminal tenha desaparecido (historicamente porque o seu modem tinha h ung -se , hoje em dia geralmente porque você fechou a janela do emulador de terminal).SIGBUS
para uma memória de acesso não alinhada;SIGSEGV
para acessar uma página não mapeada;SIGILL
para uma instrução ilegal (código incorreto);SIGFPE
para uma instrução de ponto flutuante com argumentos ruins (por exemplosqrt(-1)
).SIGALRM
notifica que um cronômetro definido pelo processo expirou. Temporizadores podem ser configurados comalarm
,setitimer
entre outros.SIGCHLD
notifica um processo que um de seus filhos morreu.SIGPIPE
é gerado quando um processo tenta gravar em um canal quando o final da leitura é fechado (a idéia é que, se você executarfoo | bar
ebar
sair,foo
será morto por aSIGPIPE
).SIGPOLL
(também chamadoSIGIO
) notifica o processo que ocorreu um evento pesquisável. POSIX especifica eventos pesquisáveis registrados através doI_SETSIG
ioctl
. Muitos sistemas permitem eventos pesquisáveis em qualquer descritor de arquivo, definido através doO_ASYNC
fcntl
sinalizador. Um sinal relacionado é oSIGURG
que notifica dados urgentes em um dispositivo (registrado viaI_SETSIG
ioctl
) ou soquete .SIGPWR
é enviado a todos os processos quando o no- break sinaliza que uma falha de energia é iminente.Essas listas não são exaustivas. Sinais padrão são definidos em
signal.h
.A maioria dos sinais pode ser capturada e manipulada (ou ignorada) pelo aplicativo. Os únicos dois sinais portáteis que não podem ser capturados são
SIGKILL
(apenas morrer) eSTOP
(interromper a execução).SIGSEGV
( falha de segmentação ) e seu primoSIGBUS
( erro de barramento ) podem ser detectados, mas é uma má idéia, a menos que você realmente saiba o que está fazendo. Um aplicativo comum para capturá-los é imprimir um rastreamento de pilha ou outras informações de depuração. Um aplicativo mais avançado é implementar algum tipo de gerenciamento de memória em processo ou interceptar instruções incorretas nos mecanismos das máquinas virtuais.Finalmente, deixe-me mencionar algo que não é um sinal. Quando você pressiona Ctrl+ Dno início de uma linha em um programa que está lendo a entrada do terminal, isso indica ao programa que o final do arquivo de entrada foi atingido. Isso não é um sinal: é transmitido pela API de entrada / saída. Como Ctrl+ Ce amigos, a chave pode ser configurada com
stty
.fonte
SIGFPE
:, de maneira não intuitiva, também é sinalizada no número inteiro dividido por zero e, às vezes, no excesso de número inteiro assinado.Para responder à sua segunda pergunta primeiro:
SIGSTOP
eSIGKILL
não pode ser capturado pelo aplicativo, mas todos os outros sinais podem, inclusiveSIGSEGV
. Essa propriedade é útil para depuração - por exemplo, com o suporte correto da biblioteca, você pode escutarSIGSEGV
e gerar um backtrace de pilha para mostrar exatamente onde esse segfault aconteceu.A palavra oficial (para o Linux, de qualquer maneira) sobre o que cada sinal faz está disponível digitando
man 7 signal
em uma linha de comando do Linux. http://linux.die.net/man/7/signal tem as mesmas informações, mas as tabelas são mais difíceis de ler.No entanto, sem alguma experiência com sinais, é difícil saber pelas breves descrições o que eles fazem na prática, então aqui está minha interpretação:
Acionado pelo teclado
SIGINT
acontece quando você bateCTRL+C
.SIGQUIT
é acionado porCTRL+\
e despeja o núcleo.SIGTSTP
suspende seu programa quando você bateCTRL+Z
. Ao contrárioSIGSTOP
, é alcançável, o que dá aos programasvi
a chance de redefinir o terminal para um estado seguro antes de se suspender.Interações terminais
SIGHUP
("hangup") é o que acontece quando você fecha o xterm (ou desconecta o terminal) enquanto o programa está em execução.SIGTTIN
eSIGTTOU
pause seu programa se ele tentar ler ou gravar no terminal enquanto estiver em execução em segundo plano. ParaSIGTTOU
que isso aconteça, acho que o programa precisa estar gravando/dev/tty
, não apenas o stdout padrão.Acionado por uma exceção de CPU
Isso significa que seu programa tentou fazer algo errado.
SIGILL
significa uma instrução ilegal ou desconhecida do processador. Isso pode acontecer se você tentar acessar as portas de E / S do processador diretamente, por exemplo.SIGFPE
significa que houve um erro de matemática no hardware; provavelmente o programa tentou dividir por zero.SIGSEGV
significa que seu programa tentou acessar uma região não mapeada da memória.SIGBUS
significa que o programa acessou a memória incorretamente de alguma outra maneira; Não entrarei em detalhes neste resumo.Interação de processo
SIGPIPE
acontece se você tentar gravar em um tubo depois que o leitor do tubo fechar sua extremidade. Vejaman 7 pipe
.SIGCHLD
acontece quando um processo filho que você criou fecha ou é suspenso (porSIGSTOP
ou semelhante).Útil para auto-sinalização
SIGABRT
geralmente é causado pelo programa que chama aabort()
função e causa um dump principal por padrão. Uma espécie de "botão de pânico".SIGALRM
é causado pelaalarm()
chamada do sistema, que fará com que o kernel entregue umSIGALRM
programa ao programa após um número especificado de segundos. Vejaman 2 alarm
eman 2 sleep
.SIGUSR1
eSIGUSR2
são usados como o programa gosta. Eles podem ser úteis para sinalizar entre processos.Enviado pelo administrador
Esses sinais geralmente são enviados a partir do prompt de comandos, via
kill
comando,fg
oubg
no caso deSIGCONT
.SIGKILL
eSIGSTOP
são os sinais desbloqueáveis. O primeiro sempre termina o processo imediatamente; o segundo suspende o processo.SIGCONT
retoma um processo suspenso.SIGTERM
é uma versão capturável deSIGKILL
.fonte
shutdown
comando é usado?SIGTERM
é enviado primeiro, seguido por um atraso, seguido porSIGKILL
. Em princípio, para um desligamento imediato e difícil, o kernel não precisa enviar nenhum sinal; poderia simplesmente parar de executar o processo.