setjmp(3) Library Functions Manual setjmp(3) BEZEICHNUNG setjmp, sigsetjmp, longjmp, siglongjmp - Nichtlokalen Sprungbefehl durchfuhren BIBLIOTHEK Standard-C-Bibliothek (libc, -lc) UBERSICHT #include int setjmp(jmp_buf Umg); int sigsetjmp(sigjmp_buf Umg, int speicherSig); [[noreturn]] void longjmp(jmp_buf Umg, int Wert); [[noreturn]] void siglongjmp(sigjmp_buf Umg, int Wert); Mit Glibc erforderliche Feature-Test-Makros (siehe feature_test_macros(7)): setjmp(): siehe ANMERKUNGEN. sigsetjmp(): _POSIX_C_SOURCE BESCHREIBUNG Die auf dieser Seite beschriebenen Funktionen werden fur >>nichtlokale Gotos<< verwandt: Ubergabe der Ausfuhrung von einer Funktion zu einer vorbestimmten Stelle in einer anderen Funktion. Die Funktion setjmp() etabliert dynamisch das Ziel, zu dem die Steuerung spater ubergeben wird und longjmp() fuhrt den Ausfuhrungstransfer aus. Die Funktion setjmp() speichert verschiedene Informationen uber die aufrufende Umgebung (typischerweise den Stack-Zeiger, den Anweisungszeiger, moglicherweise die Werte von anderen Registern und die Signalmaske) im Puffer Umg fur die spatere Verwendung durch longjmp(). In diesem Fall liefert setjmp() 0 zuruck. Die Funktion longjmp() verwendet die in Umg gespeicherten Informationen, um die Steuerung zu dem Punkt zuruckzuubergeben, an dem setjmp() aufgerufen worden war und den Stack auf seinem Zustand zum Zeitpunkt des Aufrufs von setjmp() wiederherzustellen (>>zuruckzuspulen<<). Zusatzlich und abhangig von der Implementierung (siehe ANMERKUNGEN) konnen die Werte einiger anderer Register und der Prozesssignalmaske auf den Wert zum Zeitpunkt des Aufrufs von setjmp() wiederhergestellt werden. Nach einem erfolgreichen longjmp() fahrt die Ausfuhrung so fort, als ob setjmp() ein zweites Mal zuruckgekehrt ware. Diese >>Schummel<<-Ruckkehr kann von einem echten Aufruf von setjmp() unterschieden werden, da die >>Schummel<<-Ruckkehr den in Wert bereitgestellten Wert zuruckliefert. Falls der Programmierer fehlerhafterweise den Wert 0 in Wert weitergibt, wird die >>Schummel<<-Ruckkehr stattdessen 1 zuruckliefern. sigsetjmp() und siglongjmp() sigsetjmp() und siglongjmp() fuhren auch nichtlokale Gotos durch, stellen aber eine vorhersehbare Behandlung der Prozesssignalmaske bereit. Nur wenn das an sigsetjmp() ubergebene Argument speicherSig nicht Null ist, wird die aktuelle Signalmaske des Prozesses in Umg gespeichert und wiederhergestellt, wenn spater mit diesem Umg ein siglongjmp durchgefuhrt wird. RUCKGABEWERT setjmp() und sigsetjmp() geben 0 zuruck, wenn sie direkt aufgerufen wurden; bei dem >>nachgeahmten<< Zuruckkehren, das nach longjmp() und siglongjmp() auftritt, wird der in Wert angegebene Nichtnull-Wert zuruckgegeben. Die Funktionen longjmp() oder siglongjmp() kehren nicht zuruck. ATTRIBUTE Siehe attributes(7) fur eine Erlauterung der in diesem Abschnitt verwandten Ausdrucke. +--------------------------------+-------------------------+-----------+ |Schnittstelle | Attribut | Wert | +--------------------------------+-------------------------+-----------+ |setjmp(), sigsetjmp() | Multithread-Fahigkeit | MT-Sicher | +--------------------------------+-------------------------+-----------+ |longjmp(), siglongjmp() | Multithread-Fahigkeit | MT-Sicher | +--------------------------------+-------------------------+-----------+ STANDARDS setjmp() longjmp() C11, POSIX.1-2008. sigsetjmp() siglongjmp() POSIX.1-2008. GESCHICHTE setjmp() longjmp() POSIX.1-2001, C89. sigsetjmp() siglongjmp() POSIX.1-2001. POSIX spezifiziert nicht, ob setjmp() die Signalmaske sichern wird (um sie spater wahrend longjmp() wieder herzustellen). In System-V wird es dies nicht tun. In 4.3BSD wird es dies tun und dort gibt es eine Funktion _setjmp(), die es nicht tut. Das Verhalten unter Linux hangt von der Glibc-Version und den Einstellungen der Feature-Test-Makros ab. Vor Glibc 2.19 folgte setjmp() standardmassig dem Verhalten von System V, aber das BSD-Verhalten wird bereitgestellt, wenn das _BSD_SOURCE-Feature-Test-Macro explizit definiert ist und weder _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _GNU_SOURCE noch _SVID_SOURCE definiert ist. Seit Glibc 2.19 stellt nur die System-V-Version von setjmp() bereit. Programme, die die BSD-Semantik benotigen, sollten Aufrufe von setjmp() durch Aufrufe von sigsetjmp(), bei denen das Argument speicherSig ungleich numerisch Null ist, ersetzen. ANMERKUNGEN setjmp() und longjmp() konnen zum Umgang mit Fehlern innerhalb tiefverschachtelter Funktionsaufrufe nutzlich sein oder um einem Signal-Handler zu ermoglichen, die Steuerung an einen bestimmten Punkt in dem Programm zu ubergeben, statt zu dem Punkt zuruckzukehren, in dem der Handler das Hauptprogramm unterbrochen hat. In letzterem Falle verwenden Sie sigsetjmp() und siglongjmp(), falls Sie die Signalmaske portabel speichern und wiederherstellen mochten. Lesen Sie auch die Diskussion zur Programmlesbarkeit weiter unten. WARNUNGEN Der Compiler kann Variablen in Register optimieren und longjmp() kann die Werte anderer Register zusatzlich zum Stack- und Programmzeiger wiederherstellen. Daher ist der Wert von automatischen Variablen nach einem Aufruf von longjmp() undefiniert, falls alle folgenden Kriterien zutreffen: o sie sind fur die Funktion, die den entsprechenden Aufruf setjmp() durchfuhrte, lokal, o ihre Werte sind zwischen Aufrufen von setjmp() und longjmp() geandert, und o sie sind nicht als volatile deklariert. Entsprechende Anmerkungen gelten fur siglongjmp(). Nicht lokale GOTOs und Programmlesbarkeit Auch wenn er missbraucht werden kann, hat der traditionelle >>goto<<-Ausdruck von C zumindest den Vorteil, dass lexikalische Hinweise (der Goto-Ausdruck und die Zielmarkierung) dem Programmierer erlauben, leicht den Ablauf zu verstehen. Nichtlokale Gotos stellen keine solchen Hinweise bereit: Mehrere Aufrufe von setjmp() konnen die gleiche Variable jmp_buf einsetzen, so dass der Inhalt der Variablen sich uber die Lebensdauer des Programmes verandern kann. Konsequenterweise kann der Programmierer dazu gezwungen sein, den Code detailliert zu lesen, um das dynamische Ziel eines bestimmten Aufrufs von longjmp() zu ermitteln. (Um das Leben der Programmierer zu erleichtern, sollte jeder Aufruf von setjmp() eine eineindeutige Variable jmp_buf einsetzen.) Weitere Schwierigkeiten kommen hinzu, da die Aufrufe von setjmp() und longjmp() nicht zwingend im gleichen Quellcodemodul sein mussen. Zusammenfassend erschweren nicht lokale GOTOs das Verstandnis und die Verwaltung von Programmen. Falls moglich, sollte eine Alternative benutzt werden. Undefiniertes Verhalten Falls die Funktion, die setjmp() aufruft, zuruckkehrt, bevor longjmp() aufgerufen wird, ist das Verhalten undefiniert. Irgendwelches subtiles oder nicht so subtiles Chaos entsteht bestimmt dadurch. Falls ein longjmp()-Aufruf in einem Programm mit mehreren Threads einen Umg-Puffer einsetzt, der durch einen Aufruf von setjmp() in einem anderen Thread initialisiert wurde, ist sein Verhalten nicht definiert. POSIX.1-2008 Technische Berichtigung 2 fugt longjmp() und siglongjmp() zur Liste der asynchronsignalsicheren Funktionen hinzu. Der Standard empfiehlt jedoch den Gebrauch dieser Funktionen aus Signal-Handlern zu vermeiden. Sie fahrt damit fort, zu betonen, dass, falls diese Funktionen von einem Signal-Handler aufgerufen werden, der einen Aufruf einer nicht asynchronsignalsicheren Funktion unterbrochen hatte (oder etwas gleichbedeutendem, wie den Schritten, die exit(3) entsprechen, die uber eine Ruckkehr vom initialen Aufruf zu main() auftreten), das Verhalten nicht definiert ist, falls das Programm nachfolgend einen Aufruf einer nicht asynchronsignalsicheren Funktion durchfuhrt. Der einzige Weg, nicht definiertes Verhalten zu vermeiden, ist, eines des Nachfolgenden sicherzustellen: o Nach langen Sprungen vom Signal-Handler ruft das Programm keine asynchronsignalsicheren Funktionen auf und kehrt nicht vom initialen Aufruf von main() zuruck. o Jedes Signal, dessen Handler einen langen Sprung durchfuhrt, muss wahrend jedes Aufrufs einer nicht asynchronsignalsicheren Funktion blockiert werden und keine nicht asynchronsignalsicheren Funktionen werden nach der Ruckkehr vom initialen Aufruf von main() aufgerufen. SIEHE AUCH signal(7), signal-safety(7) UBERSETZUNG Die deutsche Ubersetzung dieser Handbuchseite wurde von Patrick Rother , Chris Leick , Dr. Tobias Quathamer , Helge Kreutzmann und Mario Blattermann erstellt. Diese Ubersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezuglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG ubernommen. Wenn Sie Fehler in der Ubersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Ubersetzer . Linux man-pages 6.06 31. Oktober 2023 setjmp(3)