Provided by: manpages-de_4.26.0-1_all 

BEZEICHNUNG
signal - Überblick über Signale (Software-Interrupts)
BESCHREIBUNG
Linux unterstützt sowohl nach POSIX zuverlässige Signale (im Folgenden: »Standard-Signale«) und
POSIX-Echtzeit-Signale.
Signalzuordnung (disposition)
Jedes Signal hat eine aktuelle Zuordnung. Sie legt fest, wie sich der Prozess verhält, wenn er das Signal
erhält.
Die Einträge in der »Aktion«-Spalte in der folgenden Tabelle legen die Standardzuordnung für jedes Signal
fest:
Term Standardaktion ist der Abbruch des Prozesses.
Ign Standardaktion ist, das Signal zu ignorieren.
Core Die Standardaktion ist der Abbruch des Prozesses und das Erstellen eines Speicherauszugs (siehe
core(5)).
Stop Die Standardaktion ist, den Prozess anzuhalten.
Cont Die Standardaktion ist, einen angehaltenen Prozess fortzusetzen.
Ein Prozess kann die Zuordnung eines Signals mit Hilfe von sigaction(2) oder signal(2) ändern. (Letzteres
ist schlechter portierbar bei der Realisierung von Signal-Handlern; siehe signal(2) für Details.) Mit
diesen Systemaufrufen kann ein Prozess eine der folgenden Verhaltensweisen bei Erhalt eines Signals
auswählen: die Standardaktion ausführen, das Signal ignorieren oder das Signal mit einem Signal-Handler
abfangen. Ein Signal-Handler ist eine vom Programmierer definierte Funktion. Sie wird automatisch
aufgerufen, wenn das Signal eintrifft.
Standardmäßig wird ein Signal-Handler auf dem normalen Prozess-Stack aufgerufen. Man kann es einrichten,
dass der Signal-Handler einen alternativen Stack benutzt; vgl. sigaltstack(2) für eine Erörterung, wie
das gemacht wird und wann es nützlich sein könnte.
Die Signalzuordnung ist ein prozessbezogenes Attribut; in einer Multithread-Anwendung ist die Zuordnung
eines bestimmten Signales für alle Threads gleich.
Ein mittels fork(2) erstellter Kindprozess erbt eine Kopie der Signalzuordnungen seines Elternprozesses.
Während eines execve(2) werden die Zuordnungen von verwalteten Signalen auf die Vorgabe zurückgesetzt;
die Zuordnung ignorierter Signale werden unverändert gelassen.
Ein Signal senden
Die folgenden Systemaufrufe und Bibliotheksfunktionen ermöglichen dem aufrufenden Programm den Versand
eines Signals:
raise(3)
sendet dem aufrufenden Thread ein Signal
kill(2)
sendet ein Signal an einen bestimmten Prozess, alle Mitglieder einer bestimmten Prozessgruppe oder
an alle Prozesse im System
pidfd_send_signal(2)
sendet ein Signal an einen Prozess, der durch einen PID-Dateideskriptor identifiziert ist.
killpg(3)
sendet ein Signal an alle Mitglieder einer bestimmten Prozessgruppe
pthread_kill(3)
sendet ein Signal an einen bestimmten POSIX-Thread im gleichen Prozess wie die aufrufende Routine
tgkill(2)
Es wird ein Signal an einen bestimmten Thread in einem bestimmten Prozess gesendet. (Mit diesem
Systemaufruf wird pthread_kill(3) realisiert.)
sigqueue(3)
sendet ein Echtzeit-Signal und zugehörige Daten an einen bestimmten Prozess
Warten auf ein abzufangendes Signal
Die folgenden Systemaufrufe setzen die Ausführung des aufrufenden Threads aus, bis ein Signal abgefangen
wird (oder ein nicht abgefangenes Signal den Prozess beendet):
pause(2)
setzt die Ausführung aus, bis irgendein Signal abgefangen wird.
sigsuspend(2)
ändert zeitweise die Signalmaske (siehe unten) und setzt die Ausführung aus, bis eines der nicht
maskierten Signale abgefangen wird.
Synchrone Signalannahme
Anstatt ein Signal asynchron mit einem Signal-Handler abzufangen, kann ein Signal auch synchron
akzeptiert werden. Das heißt, die Ausführung wird blockiert, bis das Signal gesendet wird. Dann liefert
der Kernel Informationen über das Signal an den Aufrufenden. Es gibt zwei allgemeine Möglichkeiten, das
zu tun:
• sigwaitinfo(2), sigtimedwait(2) und sigwait(3) setzen die Ausführung aus, bis ein Signal gesendet
wird, dass zu einer festgelegen Gruppe von Signalen gehört. Jeder dieser Aufrufe gibt Informationen
über das empfangene Signal zurück.
• signalfd(2) gibt einen Dateideskriptor zurück. Mit ihm können Informationen über Signale gelesen
werden, die dem Aufrufenden übermittelt werden. Jeder Aufruf von read(2) aus dieser Datei wird
blockiert, bis eines der Signale aus der im Aufruf von signalfd(2) festgelegten Menge an den
aufrufenden Prozess gesendet wird. Der von read(2) zurückgegebene Puffer enthält eine Struktur, die
das Signal beschreibt.
Signalmaske und anstehende Signale
Ein Signal kann blockiert werden. Das bedeutet, dass es erst dann gesendet wird, nachdem es
(später/verzögert) freigegeben wurde. Zwischen dem Zeitpunkt seiner Erzeugung und dem Zeitpunkt seines
Versands wird es anstehend (pending) genannt.
Jeder Thread in einem Prozess hat eine unabhängige Signalauswahl-Maske (signal mask). Sie legt den Satz
von Signalen fest, den der Thread derzeit blockiert. Ein Thread kann seine Signalauswahl-Maske mit
pthread_sigmask(3) manipulieren. In einer traditionellen Single-Threaded-Anwendung kann sigprocmask(2)
verwendet werden, um die Signalmaske zu manipulieren.
Ein mittels fork(2) erstellter Kindprozess erbt eine Kopie der Signalmaske des Elternprozeses; die
Signalmaske wird über execve(2) hinweg erhalten.
Ein Signal kann Prozess-orientiert oder Thread-orientiert sein. Ein Prozess-orientiertes Signal ist
eines, das auf einen Prozess als gesamtes zielt (und daher daran anhängig ist). Ein Signal kann
Prozess-orientiert sein, da es vom Kernel für einen Grund außer einer Hardware-Ausnahmebehandlung erzeugt
wurde oder da es mittels kill(2) oder sigqueue(3) gesandt wurde. Ein Thread-orientiertes Signal ist
eines, das auf einen bestimmten Thread abzielt. Ein Signal kann Thread-orientiert sein, da es als
Konsequenz einer Ausführung einer bestimmten Anweisung in Maschinensprache erstellt wurde, die eine
Hardware-Ausnahmebehandlung auslöste (z.B. SIGSEGV für einen ungültigen Speicherzugriff oder SIGFPE für
einen mathematischen Fehler) oder da es mit Schnittstellen wie tgkill(2) oder pthread_kill(3) auf einen
bestimmten Thread zielte.
Ein Prozess-orientiertes Signal kann an jeden der Threads ausgeliefert werden, der derzeit keine Signale
blockiert. Falls mehr als ein Thread Signale nicht blockiert, dann wählt der Kernel einen beliebigen
Thread aus, an den er das Signal ausliefert.
Ein Thread kann die aktuell für ihn anstehenden Gruppe von Signale mit sigpending(2) ermitteln. Das sind
einerseits die für diesen Thread und andererseits die für seinen Prozess bestimmten Signale.
Ein mittels fork(2) erstellter Kindprozess hat anfänglich eine leere anhängende Signalgruppe; die
anhängende Signalgruppe wird über execve(2) hinweg erhalten.
Ausführung eines Signal-Handlers
Immer wenn es einen Übergang von der Kernelmodus-Ausführung zu der Anwendungsraum-Ausführung gibt (z.B
bei der Rückkehr aus einem Systemaufruf oder Einplanung eines Threads auf einer CPU), prüft der Kernel,
ob es ein anhängendes, nicht blockiertes Signal gibt, für das der Prozess einen Signal-Handler etabliert
hat. Falls es ein solches anhängendes Signal gibt, passieren die folgenden Schritte:
(1) Der Kernel führt die notwendigen Vorbereitungsschritte zur Ausführung des Signal-Handlers durch:
(1.1) Das Signal wird aus der Menge der anhängenden Signale entfernt.
(1.2) Falls der Signal-Handler durch einen Aufruf von sigaction(2) installiert wurde, der den
Schalter SA_ONSTACK festlegte, und der Thread über einen definierten alternativen
Signal-Stack verfügt (mittels sigaltstack(2)), dann wird der Stack installiert.
(1.3) Verschiedene Teile des Signal-bezogenen Kontextes werden in ein besonderes Frame gespeichert,
das auf dem Stack erstellt wird. Die gespeicherten Informationen beinhalten:
• das Programmzählregister (d.h. die Adresse der nächsten Anweisung in dem Hauptprogramm,
die ausgeführt werden soll, wenn der Signal-Handler zurückkehrt);
• architekturabhängige Registerzustände, die zur Wiederaufnahme des unterbrochenen Programms
benötigt werden;
• die aktuelle Signal-Maske des Threads;
• die alternativen Signal-Stack-Einstellungen des Threads.
Falls der Signal-Handler mittels des Schalters SA_SIGINFO von sigaction(2) installiert wurde,
dann kann auf die obigen Informationen über das Objekt ucontext_t, auf das durch das dritte
Argument des Signal-Handlers gezeigt wird, zugegriffen werden. Dieses Objekt gibt den Zustand
wieder, bei dem das Signal ausgeliefert wurde, anstatt im Handler; beispielsweise die Maske
der in diesem Objekt gespeicherten blockierten Signale wird nicht die Maske der neuen Signale
enthalten, die mittels sigaction(2) blockiert wurden.
(1.4) Jedes bei der Registrierung des Handlers mit sigaction(2) in act->sa_mask festgelegte Signal
wird zu der Signal-Maske des Threads hinzugefügt. Das auszuliefernde Signal wird auch zu der
Signal-Maske hinzugefügt, außer SA_NODEFER wurde bei der Registrierung des Handlers
festgelegt. Diese Signale sind daher während der Ausführung des Handlers blockiert.
(2) Der Kernel konstruiert ein Frame für den Signal-Handler auf dem Stack. Der Kernel setzt den
Programmzähler für den Thread, so dass er auf die erste Anweisung der Signal-Handler-Funktion zeigt,
und konfiguriert die Rücksprungadresse für diese Funktion, so dass sie auf ein Stück Code im
Anwendungsraum zeigt, das als Signaltrampolin bekannt ist (beschrieben in sigreturn(2)).
(3) Der Kernel übergibt die Steuerung zurück an den Anwendungsraum, wo mit der Ausführung beim Anfang
der Signal-Handler-Funktion fortgefahren wird.
(4) Wenn der Signal-Handler zurückkehrt, wird die Steuerung an den Signal-Trampolin-Code übergeben.
(5) Das Signaltrampolin ruft den Systemaufruf sigreturn(2) auf, der die Informationen auf dem in Schritt
1 erstellten Stack-Frame verwendet, um den Thread in dem Zustand wiederherzustellen, in dem er vor
dem Aufruf des Signal-Handlers war. Die Signalmaske und die alternativen Signal-Stack-Einstellungen
des Threads werden als Teil dieser Prozedur wiederhergestellt. Nach Abschluss des Aufrufs von
sigreturn(2) übergibt der Kernel die Steuerung wieder an den Anwendungsraum zurück und der Thread
fährt mit der Ausführung an dem Punkt fort, an dem er durch den Signal-Handler unterbrochen wurde.
Beachten Sie, dass der abschließende Schritt nicht ausgeführt wird, falls der Signal-Handler nicht
zurückkehrt (z.B. weil die Steuerung mittels siglongjmp(3) aus dem Handler herausverlegt wurde oder der
Handler mittels execve(2) ein neues Programm ausführt). In solchen Szenarien ist es insbesondere die
Verantwortung des Programmierers, den Zustand der Signalmaske (mittels sigprocmask(2))
wiederherzustellen, falls gewünscht wird, die Blockierung der Signale aufzuheben, die beim Eintritt in
den Signal-Handler blockiert wurden. (Beachten Sie, dass siglongjmp(3) die Signal-Maske wiederherstellen
könnte oder auch nicht, abhängig vom Wert savesigs, der beim entsprechenden Aufruf von sigsetjmp(3)
festgelegt wurde.)
Vom Standpunkt des Kernels aus ist die Ausführung des Signal-Handler-Codes genau das gleiche wie die
Ausführung jedes anderen Codes im Anwendungsraum. Dies bedeutet, dass der Kernel keinerlei besondere
Zustandsinformationen aufzeichnet, die anzeigen, dass der Thread sich derzeit in der Ausführung eines
Signal-Handlers befindet. Alle notwendigen Zustandsinformationen werden in Anwendungsraum-Registern und
im Anwendungsraum-Stack verwaltet. Die Tiefe, zu der verschachtelte Signal-Handler aufgerufen werden
können, wird daher durch den Anwendungsraum-Stack begrenzt (und unterliegt daher dem Design der
Software).
Standard-Signale
Linux untersützt die nachfolgend aufgeführten Standard-Signale. Die zweite Spalte der Tabelle zeigt an,
welcher Standard (falls vorhanden) das Signal festlegt: »P1990« zeigt an, dass das Signal in dem
ursprünglichen Standard POSIX.1-1990 beschrieben wurde; »P2001« zeigt an, dass das Signal in SUSv2 und
POSIX.1-2001 hinzugefügt wurde.
Signal Standard Aktion Kommentar
──────────────────────────────────────────────────────────────────────────────────────────
SIGABRT P1990 Core Abbruchsignal von abort(3)
SIGALRM P1990 Term Timersignal von alarm(2)
SIGBUS P2001 Core Bus-Fehler (Speicherzugriffsfehler)
SIGCHLD P1990 Ign Kindprozess angehalten oder beendet
SIGCLD - Ign ein Synonym für SIGCHLD
SIGCONT P1990 Cont fortsetzen, wenn angehalten
SIGEMT - Term Emulator-Ausnahmebehandlung
SIGFPE P1990 Core Fließkomma-Ausnahmefehler
SIGHUP P1990 Term Verbindung am steuernden Terminal beendet
(aufgehängt) oder der steuernde Prozess wurde beendet
SIGILL P1990 Core ungültiger Befehl
SIGINFO - ein Synonym für SIGPWR
SIGINT P1990 Term Unterbrechung von der Tastatur
SIGIO - Term E/A jetzt möglich (4.2BSD)
SIGIOT - Core IOT-Ausnahmebehandlung; ein Synonym für SIGABRT
SIGKILL P1990 Term Kill-Signal
SIGLOST - Term Dateisperre verloren/aufgehoben (nicht verwandt)
SIGPIPE P1990 Term defekte Pipe: Schreiben in eine Pipe ohne
Leser; siehe pipe(7)
SIGPOLL P2001 Term abfragbares Ereignis (Sys V)
Synonym für SIGIO
SIGPROF P2001 Term Profiling-Timer abgelaufen
SIGPWR - Term Stromausfall (System V)
SIGQUIT P1990 Core Abbruch von der Tastatur
SIGSEGV P1990 Core ungültige Speicherreferenz
SIGSTKFLT - Term Stack-Ausnahmebehandlung am Koprozessor (nicht verwendet)
SIGSTOP P1990 Stop Stop process
SIGTSTP P1990 Stop Stop am Terminal eingegeben
SIGSYS P2001 Core Ungültiger Systemaufruf (SVr4);
siehe auch seccomp(2)
SIGTERM P1990 Term Beendigungssignal (termination signal)
SIGTRAP P2001 Core Trace-/Haltepunkt-Ausnahmebehandlung
SIGTTIN P1990 Stop Terminal-Eingabe für Hintergrundprozess
SIGTTOU P1990 Stop Terminal-Ausgabe für Hintergrundprozess
SIGUNUSED - Core synonym mit SIGSYS
SIGURG P2001 Ign dringende Gegebenheit an Socket (4.2BSD)
SIGUSR1 P1990 Term benutzerdefiniertes Signal 1
SIGUSR2 P1990 Term benutzerdefiniertes Signal 2
SIGVTALRM P2001 Term virtueller Wecker (4.2BSD)
SIGXCPU P2001 Core CPU-Zeitbegrenzung überschritten (4.2BSD)
siehe setrlimit(2)
SIGXFSZ P2001 Core Dateigrößenbegrenzung überschritten (4.2BSD)
siehe setrlimit(2)
SIGWINCH - Ign Änderung der Fenstergröße (4.3BSD, Sun)
Die Signale SIGKILL und SIGSTOP können nicht abgefangen, blockiert oder ignoriert werden.
Bis einschließlich Linux 2.2 war das Standardverhalten für SIGSYS, SIGXCPU, SIGXFSZ und (auf anderen
Architekturen als SPARC und MIPS) SIGBUS den Prozess (ohne einen Speicherauszug zu erzeugen) zu beenden.
(Auf einigen anderen UNIX-Systemen ist die Standardaktion für SIGXCPUund SIGXFSZ, den Prozess ohne einen
Speicherauszug zu beenden.) Linux 2.4 entspricht den Anforderungen von POSIX.1-2001 an diese Signale und
beendet den Prozess mit einem Speicherauszug.
SIGEMT ist nicht in POSIX.1-2001 angegeben, erscheint aber trotzdem auf den meisten anderen
UNIX-Systemen. Dort ist die Standardaktion in der Regel die Beendigung des Prozesses mit einem
Speicherauszug.
SIGPWR (nicht in POSIX.1-2001 beschrieben) wird bei seinem Eintreten von diesen anderen UNIX-Systemen
ignoriert.
SIGIO (nicht in POSIX.1-2001 beschrieben) wird standardmäßig auf verschiedenen anderen UNIX-Systemen
ignoriert.
Warteschlange und Auslieferungssemantik für Standard-Signale
Falls für einen Prozess mehrere Standard-Signale anhängig sind, ist die Reihenfolge, in der diese Signale
ausgeliefert werden, nicht spezifiziert.
Standard-Signale kennen keine Warteschlange. Falls mehrere Instanzen eines Standard-Signals erstellt
werden, während dieses Signal blockiert ist, wird nur eine Instanz des Signals als anhängig markiert (und
das Signal wird ausgeliefert, genau wenn die Blockade aufgehoben wird). Im Fall, bei dem ein
Standard-Signal bereits anhängig ist, wird die dem Signal zugehörige Struktur siginfo_t (siehe
sigaction(2)) nicht bei der Ankunft nachfolgender Instanzen des gleichen Signals überschrieben. Daher
wird der Prozess die Informationen, die zu der ersten Instanz des Signals gehören, erhalten.
Signalnummerierung für Standard-Signale
Der numerische Wert für jedes Signal wird in der nachfolgenden Tabelle angegeben. Wie in der Tabelle
gezeigt, haben viele Signale verschiedene numerische Werte auf verschiedenen Architekturen. Der erste
numerische Wert in jeder Zeile zeigt die Signalnummer auf X86, ARM und den meisten anderen Architekturen;
der zweite Wert ist für Alpha und SPARC; der dritte für MIPS und der letzte für PARISC. Ein Bindestrich
(-) zeigt an, dass ein Signal auf der entsprechenden Architektur nicht vorhanden ist.
Signal x86/ARM Alpha/ MIPS PARISC Hinweise
die meisten anderen SPARC
──────────────────────────────────────────────────────────────────────────────
SIGHUP 1 1 1 1
SIGINT 2 2 2 2
SIGQUIT 3 3 3 3
SIGILL 4 4 4 4
SIGTRAP 5 5 5 5
SIGABRT 6 6 6 6
SIGIOT 6 6 6 6
SIGBUS 7 10 10 10
SIGEMT - 7 7 -
SIGFPE 8 8 8 8
SIGKILL 9 9 9 9
SIGUSR1 10 30 16 16
SIGSEGV 11 11 11 11
SIGUSR2 12 31 17 17
SIGPIPE 13 13 13 13
SIGALRM 14 14 14 14
SIGTERM 15 15 15 15
SIGSTKFLT 16 - - 7
SIGCHLD 17 20 18 18
SIGCLD - - 18 -
SIGCONT 18 19 25 26
SIGSTOP 19 17 23 24
SIGTSTP 20 18 24 25
SIGTTIN 21 21 26 27
SIGTTOU 22 22 27 28
SIGURG 23 16 21 29
SIGXCPU 24 24 30 12
SIGXFSZ 25 25 31 30
SIGVTALRM 26 26 28 20
SIGPROF 27 27 29 21
SIGWINCH 28 28 20 23
SIGIO 29 23 22 22
SIGPOLL identisch zu SIGIO
SIGPWR 30 29/- 19 19
SIGINFO - 29/- - -
SIGLOST - -/29 - -
SIGSYS 31 12 12 31
SIGUNUSED 31 - - 31
Beachten Sie Folgendes:
• Wenn das Signal definiert ist, ist SIGUNUSED synonym zu SIGSYS. Seit Glibc 2.26 ist SIGUNUSED auf
keiner Architektur mehr definiert.
• Signal 29 ist SIGINFO / SIGPWR (synonym für den gleichen Wert) auf einer Alpha-Maschine, aber SIGLOST
auf einer SPARC.
Echtzeit-Signale
Beginnend mit Linux 2.2 unterstützt Linux Echtzeit-Signale, wie sie ursprünglich in den
POSIX.1b-Echtzeit-Erweiterungen definiert wurden (und jetzt in POSIX.1-2001 enthalten sind). Die Bereich
der unterstützten Echtzeit-Signale wird von den Makros SIGRTMIN und SIGRTMAX definiert. POSIX.1-2001
verlangt, dass eine Umsetzung mindestens _POSIX_RTSIG_MAX (8) Echtzeit-Signale unterstützt.
Der Linux-Kernel unterstützt eine Reihe von 33 verschiedenen Echtzeit-Signalen, nummeriert von 32 bis 64.
Doch die Glibc-Umsetzung der POSIX-Threads verwendet intern zwei (für NPTL) oder drei (für LinuxThreads)
Echtzeit-Signale (siehe pthreads (7)) und stellt den Wert von SIGRTMIN passend (auf 34 oder 35 ein). Da
die Zahl der verfügbaren Echtzeit-Signale je nach Glibc-Threading-Implementierung variiert und diese
Variation (entsprechend dem verfügbaren Kernel und der Glibc) zur Laufzeit auftreten kann und tatsächlich
die verfügbaren Echtzeitsignale je nach UNIX-System variieren, sollten Programme niemals mit eincodierten
Zahlen auf Echtzeit-Signale verweisen. Stattdessen sollte auf Echtzeit-Signale immer mit der Notation
SIGRTMIN+n verwiesen werden und zur Laufzeit überprüft werden, ob (SIGRTMIN+n) SIGRTMAX nicht übersteigt.
Im Gegensatz zu Standard-Signalen haben Echtzeit-Signale keine vordefinierten Bedeutungen: der gesamte
Satz von Echtzeit-Signalen kann für anwendungsspezifische Zwecke genutzt werden.
Die Standardaktion für ein nicht abgefangenes Echtzeit-Signal ist der Abbruch des Prozesses.
Echtzeit-Signale zeichnen sich durch folgende Merkmale aus:
• Von Echtzeit-Signalen können mehrere Instanzen anstehen. Im Gegensatz dazu wird beim Versand mehrerer
Instanzen eines Standard-Signals, während das Signal aktuell blockiert ist, nur eine Instanz weiter
anstehen.
• Wenn das Signal mit Hilfe von sigqueue(3) gesendet wird, kann mit ihm ein begleitender Wert (entweder
eine Ganzzahl (Integer) oder ein Zeiger) gesendet werden. Wenn der empfangende Prozess mittels des
SA_SIGINFO-Schalters für sigaction(2) einen Handler für dieses Signal implementiert, kann dieser Wert
aus dem si_value-Feld der siginfo_t-Struktur (das zweite Argument des Handlers) bestimmt werden.
Darüber hinaus können die Felder si_uid und si_pid dieser Struktur verwendet werden, um die PID und
reale Benutzerkennung des Prozesses zu erhalten, der das Signal erzeugt hat.
• Echtzeit-Signale werden in einer garantierten Reihenfolge zugestellt. Mehrere Echtzeit-Signale des
gleichen Typs werden in der Reihenfolge zugestellt, in der sie gesendet wurden. Wenn verschiedene
Echtzeit-Signale an einen Prozess geschickt werden, wird das Signal mit der niedrigsten Signalnummer
zuerst zugestellt. (D.h. niedrig nummerierte Signale haben höchste Priorität.) Im Gegensatz dazu ist
die Reihenfolge der Zustellung mehrerer für einen Prozess anstehender Standard-Signale nicht
festgelegt.
Wenn sowohl Standard- als auch Echtzeit-Signale für einen Prozess anstehen, macht POSIX keine Angabe
dazu, welche Signale zuerst zugestellt werden. Linux gibt wie auch viele andere Implementierungen den
Standard-Signalen den Vorzug.
Nach POSIX sollte eine Umsetzung mindestens _POSIX_SIGQUEUE_MAX (32) Echtzeit-Signale in der
Warteschlange eines Prozesses ermöglichen. Allerdings macht Linux das anders. Bis einschließlich Linux
2.6.7 legt Linux eine systemweite Obergrenze für die Anzahl wartender Echtzeit-Signale für alle Prozesse
fest. Diese Grenze kann eingesehen und (mit entsprechenden Rechten) durch die Datei
/proc/sys/kernel/rtsig-max geändert werden. Aus der verwandten Datei /proc/sys/kernel/rtsig-nr kann die
Anzahl der aktuell anstehenden Signale ermittelt werden. In Linux 2.6.8 wurden diese /proc-Schnittstellen
durch die Ressource RLIMIT_SIGPENDING, die einen benutzerspezifischen Grenzwert für anstehende Signale in
der Warteschlange festlegt, ersetzt (siehe setrlimit(2)).
Die Ergänzung um Echtzeitsignale erforderte die Verbreiterung der Signalmengenstruktur (sigset_t) von 32
auf 64 Bit. Konsequenterweise wurden viele Systemaufrufe durch neue Systemaufrufe abgelöst, die die
größeren Signalmengen unterstützten. Die alten und neuen Systemaufrufe sind wie folgt:
Linux 2.0 und älter Linux 2.2 und neuer
sigaction(2) rt_sigaction(2)
sigpending(2) rt_sigpending(2)
sigprocmask(2) rt_sigprocmask(2)
sigreturn(2) rt_sigreturn(2)
sigsuspend(2) rt_sigsuspend(2)
sigtimedwait(2) rt_sigtimedwait(2)
Unterbrechung von Systemaufrufen und Bibliotheksfunktionen durch Signal-Handler
Wenn ein Signal-Handler aufgerufen wird, während ein Systemaufruf oder Bibliotheksfunktionsaufruf
blockiert ist, wird entweder:
• nach Abschluss des Signal-Handlers der Aufruf neu gestartet oder
• der Aufruf schlägt mit dem Fehler EINTR fehl.
Welche dieser beiden Verhaltensweisen eintritt, hängt von der Schnittstelle und der Verwendung oder
Nichtverwendung des Schalters SA_RESTART ab (siehe sigaction(2)). Die Einzelheiten unterscheiden sich
zwischen UNIX-Systemen. Im Folgenden werden die Linux-Spezifika erörtert.
Wenn ein blockierter Aufruf einer der folgenden Schnittstellen von einem Signal-Handler unterbrochen
wird, wird der Aufruf nach der Rückkehr aus dem Signal-Handler erneut gestartet, wenn der Schalter
SA_RESTART verwendet wurde; anderenfalls schlägt der Aufruf mit dem Fehler EINTR fehl:
• Aufrufe von read(2), readv(2), write(2), writev(2) und ioctl(2) für »langsame« Geräte. Bei »langsamen«
Geräten kann ein E-/A-Aufruf für eine unbestimmte Zeit zu einer Blockade führen. Zu ihnen gehören
beispielsweise Terminals, Pipes und Sockets. Hat ein E-/A-Aufruf für ein langsames Gerät schon Daten
übertragen und wird durch einen Signal-Handler unterbrochen, wird der Aufruf mit einem Erfolgs-Status
abgeschlossen (normalerweise ist das die Zahl übertragener Bytes). Beachten Sie, dass eine (lokale)
Festplatte nach dieser Definition kein langsames Gerät ist. E/A-Aktionen auf Fesplattengeräten werden
durch Signale nicht unterbrochen.
• open(2), wenn er blockieren kann (z. B. beim Öffnen eines FIFOs; siehe fifo(7)).
• wait(2), wait3(2), wait4(2), waitid(2) und waitpid(2).
• Socket-Schnittstellen: accept(2), connect(2), recv(2), recvfrom(2), recvmmsg(2), recvmsg(2), send(2),
sendto(2) und sendmsg(2), es sei denn, es wurde für den Socket eine Zeitbegrenzung (Timeout)
festgelegt (siehe unten).
• Dateisperrende Schnittstellen: flock(2) und die Aktionen F_SETLKW und F_OFD_SETLKW von fcntl(2).
• POSIX-Schnittstellen für Nachrichten-Warteschlangen: mq_receive(3), mq_timedreceive(3), mq_send(3),
and mq_timedsend(3).
• futex(2) FUTEX_WAIT (seit Linux 2.6.22; vorher immer Fehlschlag mit EINTR).
• io_getevents(2)
• pthread_mutex_lock(3), pthread_cond_wait(3) und verwandte APIs.
• futex(2) FUTEX_WAIT_BITSET.
• POSIX-Semaphor-Schnittstellen: sem_wait(3) und sem_timedwait(3) (seit Linux 2.6.22; vorher immer
Fehlschlag mit EINTR).
• read(2) von einem inotify(7)-Dateideskriptor (seit Linux 3.8; vorher immer Fehlschlag mit EINTR).
Folgende Schnittstellen werden nach einer Unterbrechung durch einen Signal-Handler, unabhängig von der
Verwendung von SA_RESTART nie erneut gestartet; sie schlagen immer mit dem Fehler EINTR fehl:
• »Eingabe«-Socket-Schnittstellen, wenn für den Socket mittels setsockopt(2) eine Zeitbegrenzung
(Timeout, SO_RCVTIMEO) festgelegt wurde: accept(2), recv(2), recvfrom(2), recvmmsg(2) (auch mit einem
von NULL verschiedenen Argument timeout) und recvmsg(2).
• »Ausgabe«-Socket-Schnittstellen, wenn für den Socket mittels setsockopt(2) eine Zeitbegrenzung
(Timeout, SO_RCVTIMEO) festgelegt wurde: connect(2), send(2), sendto(2) und sendmsg(2).
• Schnittstellen, mit denen auf Signale gewartet wird: pause(2), sigsuspend(2), sigtimedwait(2) und
sigwaitinfo(2).
• Schnittstellen, die Dateideskriptoren mehrfach nutzen: epoll_wait(2), epoll_pwait(2), poll(2),
ppoll(2), select(2) und pselect(2).
• System-V-IPC-Schnittstellen: msgrcv(2), msgsnd(2), semop(2), and semtimedop(2).
• Schlaf-Systemaufrufe: clock_nanosleep(2), nanosleep(2), and usleep(3).
• io_getevents(2)
Die Funktion sleep(3) wird ebenfalls niemals neu gestartet, wenn sie durch einen Handler unterbrochen
wurde, wird aber erfolgreich verlassen: Der Rückgabewert ist die Zeit, die noch geschlafen werden sollte.
Unter bestimmten Umständen kann die Benachrichtigungsfunktionalität im Benutzerraum von seccomp(2) zum
Neustart von Systemaufrufen führen, die andernfalls niemals durch SA_RESTART neugestartet würden; für
Details siehe seccomp_unotify(2).
Unterbrechung von Systemaufrufen und Bibliotheksfunktionen durch Stop-Signale
Auf Linux können sogar ohne Signal-Handler bestimmte sperrende Systemaufrufe mit dem Fehler EINTR
fehlschlagen, nachdem der Prozess von einem der Stop-Signale gestoppt wird und dann mittels SIGCONT
wieder fortgesetzt. Dieses Verhalten wird von POSIX.1 nicht gebiligt und tritt nicht auf anderen Systemen
auf.
Die folgenden Linux-Schnittstellen zeigen dieses Verhalten:
• »Eingabe«-Socket-Schnittstellen, wenn für den Socket mittels setsockopt(2) eine Zeitbegrenzung
(Timeout, SO_RCVTIMEO) festgelegt wurde: accept(2), recv(2), recvfrom(2), recvmmsg(2) (auch mit einem
von NULL verschiedenen Argument timeout) und recvmsg(2).
• »Ausgabe«-Socket-Schnittstellen, wenn für den Socket mittels setsockopt(2) eine Zeitbegrenzung
(Timeout, SO_RCVTIMEO) festgelegt wurde: connect(2), send(2), sendto(2) und sendmsg(2), falls eine
Sendezeitüberschreitung (SO_SNDTIMEO) gesetzt wurde.
• epoll_wait(2), epoll_pwait(2).
• semop(2), semtimedop(2).
• sigtimedwait(2), sigwaitinfo(2).
• Linux 3.7 und älter: read(2) von einem inotify(7)-Dateideskriptor
• Linux 2.6.21 und früher: futex(2) FUTEX_WAIT, sem_timedwait(3), sem_wait(3).
• Linux 2.6.8 und früher: msgrcv(2), msgsnd(2).
• Linux 2.4 und früher: nanosleep(2).
STANDARDS
POSIX.1, mit den beschriebenen Ausnahmen
ANMERKUNGEN
Für eine Diskussion asynchron-Signal-sicherer Funktionen, siehe signal-safety(7).
Die Datei /proc/PID/task/[TID]/status enthält verschiedene Felder, die die Signale, die ein Thread
blockiert (SigBlk), abfängt (SigCgt) oder ignoriert (SigIgn) zeigt. (Die Gruppe der abgefangenen oder
ignorierten Signale wird für alle Threads eines Prozesses identisch sein.) Andere Felder zeigen die
Gruppe der anhängenden Signale, die für den Thread bestimmt sind (SigPnd) sowie die Gruppe der
anhängenden Signale, die für den Prozess als ganzes bestimmt sind (ShdPnd). Die entsprechenden Felder in
/proc/PID/status zeigen die Informationen für den Haupt-Thread. Siehe proc(5) für weitere Details.
FEHLER
Es gibt sechs Signale, die als Konsequenz aus einer Hardware-Ausnahmebehandlung ausgeliefert werden
können: SIGBUS, SIGEMT, SIGFPE, SIGILL, SIGSEGV und SIGTRAP. Welches dieser Signale für eine bestimmte
Hardware-Ausnahmebehandlung ausgeliefert wird, ist nicht dokumentiert und ergibt nicht immer Sinn.
Zum Beispiel kann ein ungültiger Speicherzugriff, der die Auslieferung von SIGSEGV auf einer
CPU-Architektur hervorruft, die Auslieferung von SIGBUS auf einer anderen Architektur (oder andersherum)
hervorrufen.
Als weiteres Beispiel löst die Verwendung der X86-int-Anweisung mit einem verbotenen Argument (jeder Zahl
außer 3 und 128) die Auslieferung von SIGSEGV aus, obwohl SIGILL mehr Sinn ergäbe, aufgrund der Art, wie
die CPU die verbotene Operation an den Kernel berichtet.
SIEHE AUCH
kill(1), clone(2), getrlimit(2), kill(2), pidfd_send_signal(2), restart_syscall(2), rt_sigqueueinfo(2),
setitimer(2), setrlimit(2), sgetmask(2), sigaction(2), sigaltstack(2), signal(2), signalfd(2),
sigpending(2), sigprocmask(2), sigreturn(2), sigsuspend(2), sigwaitinfo(2), abort(3), bsd_signal(3),
killpg(3), longjmp(3), pthread_sigqueue(3), raise(3), sigqueue(3), sigset(3), sigsetops(3), sigvec(3),
sigwait(3), strsignal(3), swapcontext(3), sysv_signal(3), core(5), proc(5), nptl(7), pthreads(7),
sigevent(3type)
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Eberhard Schauer
<Martin.E.Schauer@gmx.de>, Dr. Tobias Quathamer <toddy@debian.org> und Helge Kreutzmann
<debian@helgefjell.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer
bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die
Mailingliste der Übersetzer.
Linux man-pages 6.9.1 17. Juni 2024 signal(7)