Ich benutze Ubuntu 9.10 (Karmic Koala), und ich schaute mir die jmp_buf
Struktur an, die einfach ein Array von 12 Ints ist. Wenn ich setjmp
benutze und eine jmp_buf
Struktur — übertrage, werden 4 von 12 Einträgen gespeichert. Diese 4 Einträge sind der Stapelzeiger, der Rahmenzeiger, der Programmzähler und die Rücksprungadresse. Wofür sind die anderen 8 Einträge? Sind sie maschinenabhängig? Ist ein anderer Eintrag das Segmenttabellenbasisregister? Was ist noch erforderlich, um die Umgebung eines Threads/Prozesses ordnungsgemäß wiederherzustellen? Ich schaute durch die Manpage, andere Quellen, aber ich konnte den Assemblercode für setjmp
nicht finden.Was hat jeder Eintrag in der Jmp_buf-Struktur?
Antwort
auf MacOS X 10.6.2, der Header <setjmp.h>
landet <i386/setjmp.h>
verwenden, und es sagt dort:
#if defined(__x86_64__)
/*
* _JBLEN is number of ints required to save the following:
* rflags, rip, rbp, rsp, rbx, r12, r13, r14, r15... these are 8 bytes each
* mxcsr, fp control word, sigmask... these are 4 bytes each
* add 16 ints for future expansion needs...
*/
#define _JBLEN ((9 * 2) + 3 + 16)
typedef int jmp_buf[_JBLEN];
typedef int sigjmp_buf[_JBLEN + 1];
#else
/*
* _JBLEN is number of ints required to save the following:
* eax, ebx, ecx, edx, edi, esi, ebp, esp, ss, eflags, eip,
* cs, de, es, fs, gs == 16 ints
* onstack, mask = 2 ints
*/
#define _JBLEN (18)
typedef int jmp_buf[_JBLEN];
typedef int sigjmp_buf[_JBLEN + 1];
#endif
Sie wahrscheinlich ähnliche Anforderungen auf Linux finden würde - die jmp_buf
enthält genügend Informationen, um die notwendigen zu speichern Zustand. Und um es zu benutzen, müssen Sie wirklich nicht wissen, was es enthält; Alles, was Sie tun müssen, ist zu vertrauen, dass die Implementierer es richtig gemacht haben. Wenn Sie die Implementierung ändern möchten, müssen Sie dies natürlich verstehen.
Beachten Sie, dass setjmp und longjmp sehr maschinenspezifisch sind. Lesen Sie Plaugers "" für eine Diskussion über einige der Probleme, die bei der Implementierung dieser Probleme auftreten. Modernere Chips machen es schwieriger, wirklich gut zu implementieren.
setjmp
/longjmp
/sigsetjmp
sind stark von der CPU-Architektur, dem Betriebssystem und dem Threading-Modell abhängig. Die ersten beiden Funktionen (oder infamous - abhängig von Ihrem POV) erschien im ursprünglichen Unix-Kernel als eine "strukturierte" Möglichkeit, sich aus einem fehlgeschlagenen Systemaufruf wie aus einem I/O-Fehler oder anderen unangenehmen Situationen zu lösen.
Die Kommentare der Struktur in /usr/include/setjmp.h (Linux Fedora) sagen Aufrufumgebung, plus möglicherweise eine gespeicherte Signalmaske. Es enthält /usr/include/bits/setjmp.h, um jmp_buf für ein Array von sechs 32-Bit-Ints zu deklarieren, die offensichtlich spezifisch für die x86-Familie sind.
Während ich andere Quelle als PPC implementation nicht finden konnte, weisen die Kommentare darauf hin, dass FPU-Einstellungen gespeichert werden sollten. Dies ist sinnvoll, da es nicht überraschend wäre, den Rundungsmodus, die Standardoperandengröße, die Ausnahmebehandlung usw. nicht wiederherzustellen.
Es ist typisch für Systemingenieure, etwas mehr Platz zu reservieren, als tatsächlich in einer solchen Struktur benötigt wird. Ein paar zusätzliche Bytes sind kaum etwas zum Schwitzen - besonders in Anbetracht der Seltenheit der tatsächlichen Verwendung von setjmp
/longjmp
. Zu wenig Platz ist definitiv eine Gefahr. Der hervorstechendste Grund, den ich mir vorstellen kann, besteht darin, dass die Version der Laufzeitbibliothek geändert werden muss, um mehr Platz in jmp_buf zu benötigen, da zusätzlicher Raum bereits reserviert ist. Es besteht keine Notwendigkeit, Programme erneut zu kompilieren es.
- 1. Jeder hat SMA * Suchalgorithmus implementiert?
- 2. QTableView hat unerwünschte Kontrollkästchen in jeder Zelle
- 3. Jeder hat Erfahrung mit AppScale?
- 4. Eclipse Neon Voreinstellungen hat Android-Eintrag
- 5. Was ist der DNS-Eintrag, der von Kubedns protokolliert wird?
- 6. CLGeocodeCompletionHandler hat nur eine Ortsmarke Eintrag
- 7. Jeder hat einen UITypeEditor, der System.Type-Instanzen auswählt?
- 8. Hat jeder Thread seinen eigenen Stack?
- 9. Was ist der Unterschied zwischen Enthält und Jeder in LINQ?
- 10. Was ist der Unterschied zwischen "Alle" und "Jeder" in Großbuchstaben?
- 11. Hat jeder Zweig ein separates Versteck?
- 12. Jeder hat einige TAP oder SNPP Beispiele?
- 13. CardView hat zusätzlichen Rand in jeder Kante auf Pre-Lollipop
- 14. Hat jeder Benutzer eine eigene Datenbanktabelle?
- 15. Was bedeutet, dass jeder Code
- 16. Was bedeutet "der Agent hat keine Identitäten"?
- 17. Fähigkeit zu erfassen, was Benutzer auf der Webseite getan hat
- 18. Identifizieren des Kernel-Moduls, das einen sysfs-Eintrag erstellt hat
- 19. Ein Eintrag in Liste der Tupel
- 20. Django finden ältesten Eintrag in der Datenbank
- 21. Erweitern der Limesurvey-Steuerelemente in jedem Eintrag
- 22. Jeder leitet Tabelle muss eine eigenen Alias in mysql hat
- 23. Was bedeutet "StartupWMMClass" -Eintrag aus einer .desktop-Datei in Ubuntu?
- 24. Kann ein C# ENUM-Eintrag einen Bindestrich im Namen hat
- 25. Was sind die Nachteile der Einstellung jeder Eigenschaft zu stark?
- 26. Was ist _GLIBCXX_VISIBILITY? Folgendes an der Spitze jeder Kopf
- 27. Was bedeutet ein Eintrag "action = '?" In HTML-Form?
- 28. Löschen Sie einen Eintrag aus der Eigenschaftendatei
- 29. Was ist die Größe jeder Anweisung asm?
- 30. Welche Bedeutung hat die Standard-AEM-Benutzergruppe "Jeder"?