Como é que gcc implementar pilha desenrolamento de exceções C ++ em linux?
Pergunta
Como é que gcc implementar desenrolar de pilha para C ++ exceções no linux? Em particular, como ele sabe que destruidores para chamar quando desenrolando um quadro (ou seja, que tipo de informação é armazenada e onde é armazenado)?
Solução
Veja a seção 6.2 do x86_64 ABI . Esta detalhes da interface, mas não um monte dos dados subjacentes. Isto também é independente de C ++ e podia concebivelmente ser usada para outros fins como bem.
Existem basicamente duas seções do binário ELF como emitida por gcc que são de interesse para o tratamento de exceção. Eles são .eh_frame
e .gcc_except_table
.
.eh_frame
segue o formato ANÃO (o formato de depuração que vem principalmente em jogo quando você está usando GDB). Ele tem exatamente o mesmo formato da seção .debug_frame
emitido quando compilando com -g
. Essencialmente, ele contém as informações necessárias para aparecer de volta ao estado dos registros da máquina e a pilha em qualquer ponto mais alto da pilha de chamadas. Veja o padrão do anão no dwarfstd.org para mais informações sobre este assunto.
.gcc_except_table
contém informações sobre a manipulação de exceção "aterrissagem" os locais de manipuladores. Isso é necessário, de modo a saber quando parar relaxar. Infelizmente desta secção não é bem documentada. Os únicos trechos de informação que eu tenho sido capaz de recolher vêm da lista gcc discussão. Veja particularmente este post
A parte restante da informação é, então, que interpreta código real as informações encontradas nessas seções de dados. O código relevante vive em libstdc ++ e libgcc. Não me lembro no momento em que peças viver em qual. O intérprete para a informação quadro chamada ANÃO pode ser encontrada no código fonte gcc no arquivo gcc / descontrair-dw.c
Outras dicas
Não há muita documentação disponível atualmente, no entanto, o sistema básico é que GCC traduz blocos try / catch para chamadas de função e, em seguida, links em uma biblioteca com o precisava de apoio runtime ( documentação sobre o código de construção árvore inclui a declaração "lançar uma exceção não é diretamente representado em GIMPLE, uma vez que é implementado por chamar uma função").
Infelizmente eu não estou familiarizado com essas funções e não pode dizer o que a olhar para (que não seja a fonte para libgcc - que inclui a manipulação de exceção de tempo de execução).
Há uma " tratamento de exceção para Iniciantes " documento disponível.
Embora isso parece ser para Itanium, presumivelmente a implementação é semelhante para x86: tratamento de exceção ABI