Cosa causa l'invio di vari segnali?


28

A volte mi confondo un po 'tutti i segnali che un processo può ricevere. A quanto ho capito, un processo ha un gestore predefinito ( disposizione del segnale ) per ciascuno di questi segnali, ma può fornire il proprio gestore chiamando sigaction().

Quindi, ecco la mia domanda: cosa causa l'invio di ciascuno dei segnali? Mi rendo conto che è possibile inviare manualmente segnali ai processi in esecuzione tramite il -sparametro a kill, ma quali sono le circostanze naturali in cui vengono inviati questi segnali? Ad esempio, quando SIGINTviene inviato?

Inoltre, ci sono restrizioni su quali segnali possono essere gestiti? È anche SIGSEGVpossibile elaborare i segnali e restituire il controllo all'applicazione?


Una risposta adeguata a questo sarà epica e fondamentalmente replicherà le informazioni nell'articolo di Wikipedia sull'argomento, quindi indicherò lì.
Shawn J. Goff,

@Shawn: l'articolo di Wikipedia ha un elenco di segnali, ma nessuna presentazione chiara di chi invia quali segnali.
Gilles 'SO- smetti di essere malvagio' il

Risposte:


41

Oltre alla chiamata dei processi kill(2), alcuni segnali vengono inviati dal kernel (o talvolta dal processo stesso) in varie circostanze:

  • I driver del terminale inviano segnali corrispondenti a vari eventi:
    • Notifiche chiave: SIGINT(torna al ciclo principale) su Ctrl+ C, SIGQUIT(esci immediatamente) su Ctrl+ \, SIGTSTP(sospendi) su Ctrl+ Z. Le chiavi possono essere modificate con il sttycomando.
    • SIGTTINe SIGTTOUvengono inviati quando un processo in background tenta di leggere o scrivere sul suo terminale di controllo.
    • SIGWINCH viene inviato per segnalare che la dimensione della finestra del terminale è cambiata.
    • SIGHUPviene inviato al segnale che il terminale è scomparso (storicamente perché il modem aveva h ung up , al giorno d'oggi di solito perché avete chiuso la finestra di emulatore di terminale).
  • Alcune trappole del processore possono generare un segnale. I dettagli dipendono dall'architettura e dal sistema; ecco alcuni esempi tipici:
    • SIGBUS per una memoria di accesso non allineata;
    • SIGSEGV per un accesso a una pagina non mappata;
    • SIGILL per un'istruzione illegale (codice operativo errato);
    • SIGFPEper un'istruzione in virgola mobile con argomenti non validi (ad es sqrt(-1).).
  • Numerosi segnali segnalano al processo di destinazione che si è verificato un evento di sistema:
    • SIGALRMnotifica che un timer impostato dal processo è scaduto. Timer può essere impostato con alarm, setitimere altri.
    • SIGCHLD notifica a un processo che uno dei suoi figli è morto.
    • SIGPIPEviene generato quando un processo tenta di scrivere su una pipe quando la fine della lettura è stata chiusa (l'idea è che se corri foo | bared baresci, fooviene ucciso da un SIGPIPE).
    • SIGPOLL(chiamato anche SIGIO) notifica al processo che si è verificato un evento pollable. POSIX specifica gli eventi pollable registrati tramite I_SETSIG ioctl. Molti sistemi consentono eventi pollable su qualsiasi descrittore di file, impostato tramite il O_ASYNC fcntlflag. Un segnale correlato è SIGURG, che notifica i dati urgenti su un dispositivo (registrato tramite I_SETSIG ioctl) o presa .
    • Su alcuni sistemi, SIGPWRviene inviato a tutti i processi quando l' UPS segnala che è imminente un'interruzione di corrente.

Questi elenchi non sono esaustivi. I segnali standard sono definiti in signal.h.

La maggior parte dei segnali può essere catturata e gestita (o ignorata) dall'applicazione. Gli unici due segnali portatili che non possono essere catturati sono SIGKILL(basta morire) e STOP(interrompere l'esecuzione).

SIGSEGV( errore di segmentazione ) e suo cugino SIGBUS( errore del bus ) possono essere colti, ma è una cattiva idea se non sai davvero cosa stai facendo. Un'applicazione comune per catturarli è la stampa di una traccia dello stack o altre informazioni di debug. Un'applicazione più avanzata è implementare una sorta di gestione della memoria in-process o intrappolare cattive istruzioni nei motori di macchine virtuali.

Infine, vorrei menzionare qualcosa che non è un segnale. Quando si preme Ctrl+ Dall'inizio di una riga in un programma che legge l'input dal terminale, questo indica al programma che è stata raggiunta la fine del file di input. Questo non è un segnale: viene trasmesso tramite l'API di input / output. Come Ctrl+ Ce gli amici, la chiave può essere configurata con stty.


E SIGHUP, il tuo modem ha riagganciato. :-)
Keith

1
Un'altra cosa da notare SIGFPE:, in qualche modo non intuitivo, viene anche segnalato su un intero diviso per zero, e talvolta su un overflow di numeri interi con segno .
effimero

18

Per rispondere prima alla tua seconda domanda: SIGSTOPe SIGKILLnon può essere catturato dall'applicazione, ma ogni altro segnale può, anche SIGSEGV. Questa proprietà è utile per il debug: ad esempio, con il giusto supporto di libreria, è possibile ascoltare SIGSEGVe generare una backtrace dello stack per mostrare esattamente dove si è verificato il segfault.

La parola ufficiale (per Linux, comunque) su ciò che fa ogni segnale è disponibile digitando man 7 signalda una riga di comando di Linux. http://linux.die.net/man/7/signal ha le stesse informazioni, ma le tabelle sono più difficili da leggere.

Tuttavia, senza una certa esperienza con i segnali, è difficile sapere dalle brevi descrizioni cosa fanno in pratica, quindi ecco la mia interpretazione:

Attivato dalla tastiera

  • SIGINTsuccede quando colpisci CTRL+C.
  • SIGQUITviene attivato da CTRL+\e scarica core.
  • SIGTSTPsospende il programma quando si colpisce CTRL+Z. Diversamente SIGSTOP, è acquistabile, il che offre ai programmi la vipossibilità di ripristinare il terminale in uno stato sicuro prima di sospendere se stessi.

Interazioni terminali

  • SIGHUP ("hangup") è ciò che accade quando si chiude xterm (o si disconnette in altro modo il terminale) mentre il programma è in esecuzione.
  • SIGTTINe SIGTTOUmettere in pausa il programma se tenta di leggere o scrivere sul terminale mentre è in esecuzione in background. Perché SIGTTOUciò accada, penso che il programma debba scrivere /dev/tty, non solo standard stdout.

Attivato da un'eccezione della CPU

Ciò significa che il tuo programma ha tentato di fare qualcosa di sbagliato.

  • SIGILLindica un'istruzione del processore illegale o sconosciuta. Ciò può accadere se, ad esempio, si è tentato di accedere direttamente alle porte I / O del processore.
  • SIGFPEsignifica che si è verificato un errore matematico hardware; molto probabilmente il programma ha cercato di dividere per zero.
  • SIGSEGV significa che il tuo programma ha tentato di accedere a un'area di memoria non mappata.
  • SIGBUSsignifica che il programma ha avuto accesso errato alla memoria in qualche altro modo; Non entrerò nei dettagli per questo riassunto.

Interazione di processo

  • SIGPIPEsuccede se provi a scrivere su una pipe dopo che il lettore della pipe ha chiuso la loro estremità. Vedere man 7 pipe.
  • SIGCHLDsi verifica quando un processo figlio creato viene chiuso o sospeso (da SIGSTOPo simile).

Utile per l'auto-segnalazione

  • SIGABRTdi solito è causato dal programma che chiama la abort()funzione e causa un dump principale per impostazione predefinita. Ordinamento di un "pulsante antipanico".
  • SIGALRMè causato dalla alarm()chiamata di sistema, che farà in modo che il kernel consegni un SIGALRMprogramma al programma dopo un determinato numero di secondi. Vedi man 2 alarme man 2 sleep.
  • SIGUSR1e SIGUSR2vengono utilizzati comunque come piace al programma. Potrebbero essere utili per la segnalazione tra processi.

Inviato dall'amministratore

Questi segnali vengono generalmente inviati dal prompt dei comandi, tramite il killcomando o fgo bgnel caso di SIGCONT.

  • SIGKILLe SIGSTOPsono i segnali sbloccabili. Il primo termina sempre immediatamente il processo; il secondo sospende il processo.
  • SIGCONT riprende un processo sospeso.
  • SIGTERMè una versione catchable di SIGKILL.

Quale segnale viene inviato quando shutdownsi utilizza il comando?
Nathan Osman,

Dipende dagli script di spegnimento. In genere, SIGTERMviene inviato per primo, seguito da un ritardo, seguito da SIGKILL. In linea di principio, per un arresto immediato e immediato, il kernel non ha bisogno di inviare alcun segnale; potrebbe semplicemente smettere di eseguire il processo.
Jander
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.