Esta es una pregunta de segunda mano de un sitio de desarrollo de SO, pero me dio curiosidad ya que no pude encontrar una explicación decente en ninguna parte.
Al compilar y vincular un programa C ++ independiente usando gcc, a veces ocurre un error de vinculador como este:
out/kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
Aparentemente, esto se debe a que este símbolo está definido en libstdc ++, que falta en un entorno independiente. Solucionar el problema simplemente requiere definir este símbolo en alguna parte:
void *__gxx_personality_v0;
Lo cual es bueno, pero no me gustan las cosas que simplemente funcionan mágicamente ... Entonces la pregunta es, ¿cuál es el propósito de este símbolo?
-fno-exceptions
. AgreguéCPPFLAGS += -fno-exceptions
a mi archivo MAKE y eso resolvió el error.Es parte del manejo de excepciones. El mecanismo gcc EH permite mezclar varios modelos EH, y se invoca una rutina de personalidad para determinar si una excepción coincide, qué finalización invocar, etc. Esta rutina de personalidad específica es para el manejo de excepciones de C ++ (a diferencia de, digamos, gcj / Java manejo de excepciones).
fuente
El manejo de excepciones se incluye en las implementaciones independientes.
La razón de esto es que posiblemente lo use
gcc
para compilar su código. Si compila con la opción-###
, notará que falta la opción del vinculador-lstdc++
cuando invoca el proceso del vinculador. Compilar cong++
incluirá esa biblioteca y, por lo tanto, los símbolos definidos en ella.fuente
file.cpp
con engcc
lugar deg++
?libstdc++
es la única diferencia entre los dos.Un grep rápido de la
libstd++
base del código reveló los siguientes dos usos de__gx_personality_v0
:En libsupc ++ / desenrollar-cxx.h
En libsupc ++ / eh_personality.cc
(Nota: en realidad es un poco más complicado que eso; hay una compilación condicional que puede cambiar algunos detalles).
Entonces, siempre que su código no esté usando realmente el manejo de excepciones, definir el símbolo como
void*
no afectará nada, pero tan pronto como lo haga, se bloqueará:__gxx_personality_v0
es una función, no un objeto global, así que intentar llamar a la función va a saltar a la dirección 0 y provocar una falla de segmento.fuente
Tuve este error una vez y descubrí el origen:
Estaba usando un compilador gcc y mi archivo fue llamado a
CLIENT.C
pesar de que estaba haciendo un programa en C y no en un programa C ++.gcc reconoce la
.C
extensión como programa C ++ y la.c
extensión como programa C (tenga cuidado con la c pequeña y la C grande).Así que cambié el nombre de mi
CLIENT.c
programa de archivos y funcionó.fuente
Las respuestas anteriores son correctas: se usa en el manejo de excepciones. El manual de la versión 6 de GCC tiene más información (que ya no está presente en el manual de la versión 7). El error puede surgir al vincular una función externa que, desconocida para GCC, arroja excepciones de Java.
fuente