Question

J'utilise Ubuntu 9.10 (Karmic Koala) et j’ai jeté un coup d’œil à la structure jmp_buf qui est simplement un tableau de 12 ints. Lorsque j'utilise setjmp et que je passe une <=> structure & # 8212; 4 entrées sur 12 sont sauvegardées. Ces 4 entrées sont le pointeur de pile, le pointeur de trame, le compteur de programme et l'adresse de retour. A quoi servent les 8 autres entrées? Sont-ils dépendants de la machine? Une autre entrée est-elle le registre de base de la table de segments? Quoi d'autre est nécessaire pour restaurer correctement l'environnement d'un thread / processus? J'ai parcouru la page de manuel, d'autres sources, mais je n'ai pas trouvé le code d'assemblage pour <=>.

Était-ce utile?

La solution

Sous MacOS X 10.6.2, l'en-tête <setjmp.h> se termine par <i386/setjmp.h> et indique:

#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

Vous trouverez probablement des exigences similaires sous Linux - le jmp_buf contient suffisamment d’informations pour stocker l’état nécessaire. Et, pour l'utiliser, vous n'avez vraiment pas besoin de savoir ce qu'il contient. tout ce que vous avez à faire, c'est de vous assurer que les développeurs l'ont bien compris. Si vous souhaitez modifier la mise en œuvre, vous devez bien sûr la comprendre.

Notez que setjmp et longjmp sont très spécifiques à la machine. Lire la & Quot; bibliothèque Standard C de Plauger & Quot; pour discuter de certaines des questions liées à leur mise en œuvre. Des puces plus modernes rendent la mise en œuvre vraiment difficile.

Autres conseils

setjmp / longjmp / sigsetjmp dépendent fortement de l'architecture de la CPU, du système d'exploitation et du modèle de thread. Les deux premières fonctions connues (ou tristement célèbres & # 8212; selon votre POV) sont apparues dans le noyau Unix d’origine sous la forme & "; Structuré &"; moyen de se détendre après un appel système ayant échoué, à la suite d’une erreur d’entrée / sortie ou d’autres situations désagréables.

Les commentaires de la structure dans /usr/include/setjmp.h (Linux Fedora) disent Environnement d’appel, plus éventuellement un masque de signal enregistré. Il inclut /usr/include/bits/setjmp.h pour déclarez que jmp_buf a un tableau de six ints 32 bits, apparemment spécifique à la famille x86.

Alors que je ne pouvais pas trouver une source autre qu'un implémentation de PPC , les commentaires suggèrent que les paramètres de la FPU doivent être enregistrés. Cela a du sens car ne pas rétablir le mode d’arrondi, la taille par défaut des opérandes, la gestion des exceptions, etc. serait surprenant.

Il est typique des ingénieurs système de réserver un peu plus d’espace que nécessaire dans une telle structure. Quelques octets supplémentaires ne transpirent guère & # 8212, surtout si l’on considère la rareté des utilisations effectives de <=> / <=>. Avoir trop peu d'espace est sans aucun doute un danger. La raison la plus saillante à laquelle je peux penser est d'avoir un & # 8212 supplémentaire, par opposition à être sur place sur & # 8212; c'est que si la version de la bibliothèque d'exécution est modifiée pour nécessiter plus d'espace dans jmp_buf, en ayant déjà suffisamment d'espace réservé, il n'y a pas besoin de recompiler les programmes qui y font référence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top