Wodurch werden verschiedene Signale gesendet?


28

Ich bin manchmal ein wenig verwirrt von all den Signalen, die ein Prozess empfangen kann. Soweit ich weiß, hat ein Prozess für jedes dieser Signale einen Standard-Handler ( Signaldisposition ), kann jedoch durch Aufrufen einen eigenen Handler bereitstellen sigaction().

Hier ist also meine Frage: Wodurch werden die einzelnen Signale gesendet? Ich weiß, dass Sie über den -sParameter to manuell Signale an laufende Prozesse senden können. Unter killwelchen natürlichen Umständen werden diese Signale gesendet? Wann wird zum Beispiel SIGINTgesendet?

Gibt es auch Einschränkungen, mit welchen Signalen umgegangen werden kann? Können sogar SIGSEGVSignale verarbeitet und die Steuerung an die Anwendung zurückgegeben werden?


Eine richtige Antwort auf diese Frage wird episch sein und im Grunde die Informationen im Wikipedia-Artikel zu diesem Thema wiederholen, also werde ich nur darauf hinweisen.
Shawn J. Goff

@Shawn: Der Wikipedia-Artikel enthält eine Liste von Signalen, aber keine klare Darstellung, wer welche Signale sendet.
Gilles 'SO- hör auf böse zu sein'

Antworten:


41

Zusätzlich zu den aufrufenden Prozessen kill(2)werden einige Signale vom Kernel (oder manchmal vom Prozess selbst) unter verschiedenen Umständen gesendet:

  • Terminal-Treiber senden Signale, die verschiedenen Ereignissen entsprechen:
    • Tastendruckbenachrichtigungen: SIGINT(bitte kehren Sie zur Hauptschleife zurück) am Ctrl+ C, SIGQUIT(bitte sofort beenden) am Ctrl+ \, SIGTSTP(bitte aussetzen) am Ctrl+ Z. Die Schlüssel können mit dem sttyBefehl geändert werden .
    • SIGTTINund SIGTTOUwerden gesendet, wenn ein Hintergrundprozess versucht, auf sein steuerndes Terminal zu lesen oder zu schreiben.
    • SIGWINCH wird gesendet, um anzuzeigen, dass sich die Größe des Terminalfensters geändert hat.
    • SIGHUPgesendet wird , um das Signal , dass das Terminal verschwunden ist ( in der Vergangenheit , weil Ihr Modem hatte h UNG bis heutzutage in der Regel , weil Sie den Terminal - Emulator - Fenster haben geschlossen).
  • Einige Prozessor-Traps können ein Signal erzeugen. Die Details sind architektur- und systemabhängig. Hier sind typische Beispiele:
    • SIGBUS für einen nicht ausgerichteten Zugriffsspeicher;
    • SIGSEGV für einen Zugriff auf eine nicht zugeordnete Seite;
    • SIGILL für eine illegale Anweisung (falscher Opcode);
    • SIGFPEfür einen Gleitkomma-Befehl mit schlechten Argumenten (zB sqrt(-1)).
  • Eine Reihe von Signalen benachrichtigt den Zielprozess, dass ein Systemereignis aufgetreten ist:
    • SIGALRMbenachrichtigt, dass ein vom Prozess festgelegter Timer abgelaufen ist. Timer kann Satz mit sein alarm, setitimerund andere.
    • SIGCHLD benachrichtigt einen Prozess, dass eines seiner Kinder gestorben ist.
    • SIGPIPEwird generiert, wenn ein Prozess versucht, in eine Pipe zu schreiben, wenn das Leseende geschlossen wurde (die Idee ist, dass, wenn Sie ausgeführt foo | barund beendet werden bar, foovon a getötet wird SIGPIPE).
    • SIGPOLL(auch genannt SIGIO) benachrichtigt den Prozess, dass ein abrufbares Ereignis aufgetreten ist. POSIX gibt abfragbare Ereignisse an, die über das Symbol registriert werden I_SETSIG ioctl. Viele Systeme erlauben abrufbare Ereignisse für jeden Dateideskriptor, der über das O_ASYNC fcntlFlag gesetzt wird. Ein entsprechendes Signal ist SIGURG, das über dringende Daten auf einem Gerät (registriert über die I_SETSIG ioctl) oder Socket informiert .
    • Wird bei einigen Systemen SIGPWRan alle Prozesse gesendet, wenn die USV einen bevorstehenden Stromausfall meldet.

Diese Listen erheben keinen Anspruch auf Vollständigkeit. Standardsignale sind in definiert signal.h.

Die meisten Signale können von der Anwendung erfasst und verarbeitet (oder ignoriert) werden. Die einzigen zwei tragbaren Signale, die nicht abgefangen werden können, sind SIGKILL(nur sterben) und STOP(Ausführung stoppen).

SIGSEGV( Segmentierungsfehler ) und sein Cousin SIGBUS( Busfehler ) können abgefangen werden, aber es ist eine schlechte Idee, wenn Sie nicht genau wissen, was Sie tun. Eine übliche Anwendung zum Abfangen ist das Drucken eines Stack-Trace oder anderer Debug-Informationen. Eine fortgeschrittenere Anwendung ist das Implementieren einer Art von In-Process-Speicherverwaltung oder das Abfangen falscher Anweisungen in VM-Engines.

Lassen Sie mich abschließend etwas erwähnen, das kein Signal ist. Wenn Sie in einem Programm, das Eingaben vom Terminal liest, am Anfang einer Zeile Ctrl+ drücken D, wird dem Programm mitgeteilt, dass das Ende der Eingabedatei erreicht ist. Dies ist kein Signal: Es wird über die Ein- / Ausgabe-API übertragen. Wie bei Ctrl+ Cund Freunden kann die Taste mit konfiguriert werden stty.


Und SIGHUP, Ihr Modem hat aufgelegt. :-)
Keith

1
Noch etwas zu beachten: SIGFPEEtwas unintuitiv wird dies auch beim ganzzahligen Teilen durch Null und manchmal beim vorzeichenbehafteten Ganzzahlüberlauf signalisiert .
Ephemient

18

Um Ihre zweite Frage zuerst zu beantworten: SIGSTOPund SIGKILLkann von der Anwendung nicht abgefangen werden, aber jedes andere Signal kann es sogar SIGSEGV. Diese Eigenschaft ist für das Debuggen nützlich. Mit der richtigen Bibliotheksunterstützung können Sie beispielsweise SIGSEGVeinen Stack-Backtrace abhören und generieren, um zu zeigen, wo genau dieser Fehler aufgetreten ist.

Das offizielle Wort (jedenfalls für Linux) zu den Funktionen der einzelnen Signale können Sie über man 7 signaleine Linux-Befehlszeile eingeben . http://linux.die.net/man/7/signal enthält dieselben Informationen, die Tabellen sind jedoch schwerer zu lesen.

Ohne Erfahrung mit Signalen ist es jedoch schwierig, anhand der kurzen Beschreibungen zu erkennen, was sie in der Praxis bewirken. Deshalb hier meine Interpretation:

Ausgelöst von der Tastatur

  • SIGINTpassiert, wenn du schlägst CTRL+C.
  • SIGQUITwird durch ausgelöst CTRL+\und entleert den Kern.
  • SIGTSTPUnterbricht Ihr Programm, wenn Sie drücken CTRL+Z. Im Gegensatz SIGSTOPdazu ist es catchable, was Programmen die viMöglichkeit gibt, das Terminal in einen sicheren Zustand zurückzusetzen, bevor sie sich selbst aussetzen.

Terminal Interaktionen

  • SIGHUP ("Auflegen") ist das, was passiert, wenn Sie Ihr xterm schließen (oder auf andere Weise die Verbindung zum Terminal trennen), während Ihr Programm ausgeführt wird.
  • SIGTTINund halten Sie SIGTTOUIhr Programm an, wenn es versucht, vom Terminal zu lesen oder darauf zu schreiben, während es im Hintergrund ausgeführt wird. Um das SIGTTOUzu erreichen, muss das Programm schreiben /dev/tty, nicht nur die Standard-Standardausgabe.

Ausgelöst durch eine CPU-Ausnahme

Dies bedeutet, dass Ihr Programm versucht hat, etwas falsch zu machen.

  • SIGILLbedeutet eine illegale oder unbekannte Prozessoranweisung. Dies kann beispielsweise der Fall sein, wenn Sie versuchen, direkt auf Prozessor-E / A-Ports zuzugreifen.
  • SIGFPEBedeutet, dass ein Hardware-Rechenfehler aufgetreten ist. höchstwahrscheinlich hat das Programm versucht, durch Null zu teilen.
  • SIGSEGV bedeutet, dass Ihr Programm versucht hat, auf einen nicht zugeordneten Speicherbereich zuzugreifen.
  • SIGBUSbedeutet, dass das Programm auf andere Weise falsch auf den Speicher zugegriffen hat; Ich werde nicht auf Details für diese Zusammenfassung eingehen.

Prozessinteraktion

  • SIGPIPEpassiert, wenn Sie versuchen, in eine Pipe zu schreiben, nachdem der Pipe-Reader sein Ende geschlossen hat. Sehen man 7 pipe.
  • SIGCHLDtritt auf, wenn ein von Ihnen erstellter untergeordneter Prozess beendet oder angehalten wird (von SIGSTOPoder ähnlich).

Nützlich für die Selbstsignalisierung

  • SIGABRTwird normalerweise durch das Programm verursacht, das die abort()Funktion aufruft , und verursacht standardmäßig einen Core-Dump. Eine Art "Panikknopf".
  • SIGALRMwird durch den alarm()Systemaufruf verursacht, der den Kernel veranlasst, SIGALRMnach einer festgelegten Anzahl von Sekunden ein an das Programm zu senden. Siehe man 2 alarmund man 2 sleep.
  • SIGUSR1und SIGUSR2verwendet werden aber das programm gefällt. Sie könnten für die Signalisierung zwischen Prozessen nützlich sein.

Vom Administrator gesendet

Diese Signale werden normalerweise von der Eingabeaufforderung, über den killBefehl fgoder bgim Fall von gesendet SIGCONT.

  • SIGKILLund SIGSTOPsind die nicht blockierbaren Signale. Der erste bricht den Vorgang immer sofort ab; der zweite unterbricht den Vorgang.
  • SIGCONT setzt einen angehaltenen Prozess fort.
  • SIGTERMist eine auffangbare Version von SIGKILL.

Welches Signal wird gesendet, wenn der shutdownBefehl verwendet wird?
Nathan Osman

Das hängt von den Shutdown-Skripten ab. In der Regel SIGTERMwird zuerst gesendet, gefolgt von einer Verzögerung, gefolgt von SIGKILL. Im Prinzip muss der Kernel für ein hartes, sofortiges Herunterfahren überhaupt kein Signal senden. Es könnte einfach aufhören, den Prozess auszuführen.
Jander
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.