O que faz cada entrada na estrutura de retenção jmp_buf?
Pergunta
Estou executando o Ubuntu 9.10 (Karmic Koala), e eu levei uma olhada na estrutura jmp_buf
que é simplesmente um conjunto de 12 ints. Quando uso setjmp
, e passagem de uma estrutura jmp_buf
-4 de 12 entradas são guardados fora. Estes 4 entradas são o ponteiro de pilha, ponteiro, o contador de programa e o endereço de retorno. Quais são os outros 8 entradas para? Eles são dependentes da máquina? É uma outra entrada no segmento de registo base da tabela? O que mais é necessário para restaurar adequadamente o ambiente de uma thread / do processo? Olhei através da página de homem, outras fontes, mas eu não poderia encontrar o código de montagem para setjmp
.
Solução
No MacOS X 10.6.2, as extremidades cabeçalho <setjmp.h>
usando <i386/setjmp.h>
, e aí ele diz:
#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
Você provavelmente iria encontrar requisitos semelhantes em Linux - o jmp_buf
contém informação suficiente para armazenar o estado necessário. E, para usá-lo, você realmente não precisa saber o que ela contém; tudo que você precisa fazer é confiar que os implementadores tem que corrigir. Se você quiser alterar a implementação, em seguida, você precisa entendê-la, é claro.
Note que setjmp e longjmp são muito específicas da máquina. Leia Plauger de " The Standard C Library " para uma discussão sobre algumas das questões envolvidas na sua implementação. fritas mais modernas, é mais difícil de implementar muito bem.
Outras dicas
setjmp
/ longjmp
/ sigsetjmp
são altamente dependentes da arquitetura de CPU, o sistema operacional e modelo de segmento. As duas primeiras funções famosa (ou infame-dependendo do seu POV) apareceu no kernel do Unix como uma forma "estruturada" para relaxar fora de uma chamada de sistema falhou, a partir de uma i / o erro ou outras situações desagradáveis.
Os comentários da estrutura em /usr/include/setjmp.h (Linux Fedora) digamos ambiente chamando, além de, possivelmente, uma máscara de sinal salva. Inclui /usr/include/bits/setjmp.h para declarar jmp_buf ter uma matriz de seis inteiros de 32 bits, aparentemente específico para a família x86.
Enquanto eu não poderia encontrar outra fonte que não a PPC implementação , os comentários não razoável sugerir que as configurações de FPU deve ser salvo. Isso faz sentido, já não para restaurar o arredondamento modo, padrão operando tamanho, tratamento de exceções, etc. seria surpreendente.
É típico de engenheiros de sistemas para reservar um pouco mais de espaço do que realmente precisava de tal estrutura. Alguns bytes extras são quase nada para, especialmente suor considerando a raridade de usos reais setjmp
/ longjmp
. Ter muito pouco espaço definitivamente é um perigo. A razão mais saliente que posso pensar é ter extra-ao contrário de ser local on-é que, se a versão da biblioteca de tempo de execução é alterado para precisar de mais espaço em jmp_buf, por ter espaço extra já reservado, não há nenhuma necessidade de programas de recompilação referindo-se -lo.