2009-12-01 15 views
9

Sto utilizzando Ubuntu 9.10 (Karmic Koala) e ho dato un'occhiata alla struttura jmp_buf che è semplicemente un array di 12 pollici. Quando utilizzo setjmp e passo in una struttura jmp_buf — 4 di 12 voci vengono salvate. Queste 4 voci sono il puntatore dello stack, il puntatore del frame, il contatore del programma e l'indirizzo di ritorno. A cosa servono le altre 8 voci? Sono dipendenti dalla macchina? Un'altra voce è il registro di base della tabella dei segmenti? Cos'altro è necessario per ripristinare correttamente un ambiente thread/processo? Ho esaminato la pagina man, altre fonti, ma non sono riuscito a trovare il codice assembly per setjmp.Cosa contiene ciascuna voce nella struttura Jmp_buf?

risposta

8

su MacOS X 10.6.2, l'intestazione <setjmp.h> finisce con <i386/setjmp.h>, e lì si dice:

#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 

Si potrebbe probabilmente trovare esigenze simili su Linux - il jmp_buf contiene informazioni sufficienti per memorizzare il necessario stato. E, per usarlo, non hai davvero bisogno di sapere cosa contiene; tutto ciò che devi fare è avere fiducia che gli implementatori l'abbiano capito correttamente. Se vuoi modificare l'implementazione, allora devi capirlo, ovviamente.

Si noti che setjmp e longjmp sono molto specifici della macchina. Leggi "The Standard C Library" di Plauger per una discussione su alcuni dei problemi coinvolti nella loro implementazione. Chip più moderni rendono più difficile l'implementazione davvero buona.

4

setjmp/longjmp/sigsetjmp dipendono in gran parte dall'architettura della CPU, dal sistema operativo e dal modello di threading. Le prime due funzioni notoriamente (o infamemente - a seconda del tuo POV) sono apparse nel kernel originale di Unix come un modo "strutturato" per uscire da una chiamata di sistema fallita, come da un errore di I/O o da altre situazioni sgradevoli.

I commenti della struttura in /usr/include/setjmp.h (Linux Fedora) dicono Chiamare l'ambiente, oltre a possibilmente una maschera di segnale salvata. Include /usr/include/bits/setjmp.h per dichiarare jmp_buf di avere una matrice di sei valori di 32 bit, apparentemente specifici della famiglia x86.

Sebbene non sia stato possibile trovare una sorgente diversa da uno PPC implementation, i commenti suggeriscono che le impostazioni della FPU devono essere salvate. Questo ha senso dal momento che non riescono a ripristinare la modalità di arrotondamento, la dimensione predefinita dell'operando, la gestione delle eccezioni, ecc. Sarebbe sorprendente.

E 'tipico di ingegneri di sistema di riservare un po' più spazio di quanto effettivamente necessario in una tale struttura. Alcuni byte in più non fanno quasi fatica a sudare, soprattutto considerando la rarità degli usi effettivi di setjmp/longjmp. Avere troppo poco spazio è sicuramente un pericolo. La ragione più saliente che riesco a pensare è avere qualcosa in più, piuttosto che essere puntuale: se la versione della libreria di runtime viene modificata per richiedere più spazio in jmp_buf, avendo spazio aggiuntivo già prenotato, non è necessario ricompilare i programmi che si riferiscono a esso.