Это вопрос из вторых рук с сайта разработки ОС, но он вызвал у меня любопытство, так как я нигде не мог найти достойного объяснения.
При компиляции и компоновке автономной программы на C ++ с использованием gcc иногда возникает такая ошибка компоновщика:
out/kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
Очевидно, это связано с тем, что этот символ определен в libstdc ++, который отсутствует в отдельно стоящей среде. Для решения проблемы просто необходимо где-нибудь определить этот символ:
void *__gxx_personality_v0;
Что приятно, но мне не нравятся вещи, которые просто волшебно работают ... Итак, вопрос в том, какова цель этого символа?
-fno-exceptions
. Я добавилCPPFLAGS += -fno-exceptions
в свой make-файл, и это устранило ошибку.Это часть обработки исключений. Механизм gcc EH позволяет смешивать различные модели EH, и вызывается подпрограмма индивидуальности, чтобы определить, соответствует ли исключение, какую финализацию вызывать и т. Д. Эта конкретная подпрограмма индивидуальности предназначена для обработки исключений C ++ (в отличие, скажем, от gcj / Java Обработка исключений).
источник
Обработка исключений включена в отдельные реализации.
Причина этого в том, что вы, возможно, используете его
gcc
для компиляции кода. Если вы компилируете с этой опцией,-###
вы заметите, что ей не хватает опции компоновщика,-lstdc++
когда он вызывает процесс компоновщика. Компиляция с помощьюg++
включает эту библиотеку и, следовательно, определенные в ней символы.источник
file.cpp
withgcc
вместоg++
?libstdc++
единственное различие между ними - это связывание .Быстрый просмотр
libstd++
базы кода с помощью команды grep показал следующие два использования__gx_personality_v0
:В libsupc ++ / unwind-cxx.h
В libsupc ++ / eh_personality.cc
(Примечание: на самом деле это немного сложнее; есть некоторая условная компиляция, которая может изменить некоторые детали).
Итак, пока ваш код на самом деле не использует обработку исключений, определение символа как
void*
ни на что не влияет, но как только это произойдет, вы столкнетесь с ошибкой -__gxx_personality_v0
это функция, а не какой-то глобальный объект, поэтому попробуйте для вызова функции произойдет переход к адресу 0 и вызовет segfault.источник
Однажды у меня была эта ошибка, и я выяснил ее происхождение:
Я использовал компилятор gcc, и мой файл был вызван,
CLIENT.C
несмотря на то, что я делал программу C, а не программу C ++.gcc распознает
.C
расширение как программу C ++, а.c
расширение как программу C (будьте осторожны с маленьким c и большим C).Я переименовал свою файловую
CLIENT.c
программу, и она сработала.источник
Приведенные выше ответы верны: он используется при обработке исключений. В руководстве для GCC версии 6 содержится дополнительная информация (которой больше нет в руководстве версии 7). Ошибка может возникнуть при связывании внешней функции, которая - неизвестно GCC - выдает исключения Java.
источник