Esta é uma pergunta de segunda mão de um site de desenvolvimento de sistema operacional, mas me deixou curioso, pois não consegui encontrar uma explicação decente em lugar nenhum.
Ao compilar e vincular um programa C ++ independente usando gcc, às vezes ocorre um erro de vinculador como este:
out/kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
Aparentemente, isso ocorre porque esse símbolo é definido em libstdc ++, que está ausente em um ambiente independente. Para resolver o problema, basta definir este símbolo em algum lugar:
void *__gxx_personality_v0;
O que é legal, mas eu não gosto de coisas que simplesmente funcionam magicamente ... Então a questão é: qual é o propósito deste símbolo?
-fno-exceptions
. Eu adicioneiCPPFLAGS += -fno-exceptions
ao meu makefile, e isso resolveu o erro.Faz parte do tratamento de exceções. O mecanismo gcc EH permite misturar vários modelos EH, e uma rotina de personalidade é chamada para determinar se uma exceção corresponde, qual finalização invocar, etc. Esta rotina de personalidade específica é para tratamento de exceção C ++ (em oposição a, digamos, gcj / Java manipulação de exceção).
fonte
O tratamento de exceções está incluído em implementações independentes.
A razão disso é que você possivelmente usa
gcc
para compilar seu código. Se você compilar com a opção-###
, notará que falta a opção do vinculador-lstdc++
ao invocar o processo do vinculador. Compilar comg++
incluirá essa biblioteca e, portanto, os símbolos definidos nela.fonte
file.cpp
com emgcc
vez deg++
?libstdc++
é a única diferença entre os dois.Um rápido grep da
libstd++
base de código revelou os seguintes dois usos de__gx_personality_v0
:Em libsupc ++ / unwind-cxx.h
Em libsupc ++ / eh_personality.cc
(Nota: na verdade é um pouco mais complicado do que isso; há algumas compilações condicionais que podem alterar alguns detalhes).
Então, contanto que seu código não esteja realmente usando tratamento de exceção, definir o símbolo como
void*
não afetará nada, mas assim que isso acontecer, você irá travar -__gxx_personality_v0
é uma função, não um objeto global, então tentar chamar a função vai pular para o endereço 0 e causar um segfault.fonte
Tive este erro uma vez e descobri a origem:
Eu estava usando um compilador gcc e meu arquivo foi chamado
CLIENT.C
apesar de eu estar fazendo um programa C e não um programa C ++.gcc reconhece a
.C
extensão como um programa C ++ e a.c
extensão como um programa C (cuidado com o C minúsculo e o C grande).Então, renomeei meu
CLIENT.c
programa de arquivos e funcionou.fonte
As respostas acima estão corretas: ele é usado no tratamento de exceções. O manual do GCC versão 6 contém mais informações (que não estão mais presentes no manual da versão 7). O erro pode surgir ao vincular uma função externa que - desconhecida do GCC - lança exceções Java.
fonte