Cosa contiene ciascuna voce nella struttura Jmp_buf?
Domanda
Sto eseguendo Ubuntu 9.10 (Karmic Koala) e ho dato un'occhiata alla struttura jmp_buf
che è semplicemente un array di 12 pollici. Quando uso setjmp
e passo in una <=> struttura & # 8212; 4 voci su 12 vengono salvate. Queste 4 voci sono il puntatore dello stack, il puntatore al 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 l'ambiente di un thread / processo? Ho consultato la pagina man, altre fonti, ma non sono riuscito a trovare il codice assembly per <=>.
Soluzione
Su MacOS X 10.6.2, l'intestazione <setjmp.h>
finisce per usare <i386/setjmp.h>
, e qui c'è scritto:
#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
Probabilmente troverai requisiti simili su Linux: jmp_buf
contiene informazioni sufficienti per memorizzare lo stato necessario. E, per usarlo, non hai davvero bisogno di sapere cosa contiene; tutto quello che devi fare è fidarti che gli implementatori abbiano capito bene. Se vuoi modificare l'implementazione, allora devi capirla, ovviamente.
Nota che setjmp e longjmp sono molto specifici per la macchina. Leggi & Quot di Plauger; La libreria C standard & Quot; per una discussione di alcuni dei problemi coinvolti nella loro attuazione. Chip più moderni rendono più difficile l'implementazione davvero bene.
Altri suggerimenti
setjmp
/ longjmp
/ sigsetjmp
dipendono fortemente dall'architettura della CPU, dal sistema operativo e dal modello di threading. Le prime due funzioni notoriamente (o tristemente & # 8212; a seconda del POV) sono comparse nel kernel originale di Unix come & Quot; strutturato & Quot; modo per rilassarsi da una chiamata di sistema non riuscita, ad esempio da un errore di I / O o da altre brutte situazioni.
I commenti della struttura in /usr/include/setjmp.h (Linux Fedora) dicono Ambiente chiamante, più possibilmente una maschera di segnale salvata. Include /usr/include/bits/setjmp.h a dichiarare che jmp_buf ha un array di sei ints a 32 bit, apparentemente specifici per la famiglia x86.
Sebbene non sia stato possibile trovare una fonte diversa da implementazione PPC , i commenti lì suggeriscono ragionevolmente che le impostazioni FPU dovrebbero essere salvate. Ciò ha senso poiché non riuscire a ripristinare la modalità di arrotondamento, la dimensione dell'operando predefinita, la gestione delle eccezioni, ecc. Sarebbe sorprendente.
È tipico degli ingegneri di sistema riservare un po 'più di spazio di quanto effettivamente necessario in una tale struttura. Qualche byte in più non è quasi nulla da sudare & # 8212; specialmente considerando la rarità degli usi reali di <=> / <=>. Avere troppo poco spazio è sicuramente un pericolo. Il motivo più saliente a cui riesco a pensare è avere & # 8212 in più; al contrario di essere spot in & # 8212; è che se la versione della libreria di runtime viene cambiata per avere bisogno di più spazio in jmp_buf, avendo già spazio in più riservato, non è necessario ricompilare i programmi che fanno riferimento ad esso.