Dies ist eine gebrauchte Frage von einer OS-Entwicklungsseite, die mich jedoch neugierig machte, da ich nirgendwo eine anständige Erklärung finden konnte.
Beim Kompilieren und Verknüpfen eines freistehenden C ++ - Programms mit gcc tritt manchmal ein Linkerfehler wie der folgende auf:
out/kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
Dies liegt anscheinend daran, dass dieses Symbol in libstdc ++ definiert ist, das in einer freistehenden Umgebung fehlt. Um das Problem zu beheben, muss dieses Symbol einfach irgendwo definiert werden:
void *__gxx_personality_v0;
Was schön ist, aber ich mag keine Dinge, die einfach magisch funktionieren ... Die Frage ist also, was ist der Zweck dieses Symbols?
-fno-exceptions
. IchCPPFLAGS += -fno-exceptions
habe meinem Makefile hinzugefügt , und das hat den Fehler behoben.Es ist Teil der Ausnahmebehandlung. Der gcc EH-Mechanismus ermöglicht das Mischen verschiedener EH-Modelle, und eine Persönlichkeitsroutine wird aufgerufen, um zu bestimmen, ob eine Ausnahme übereinstimmt, welche Finalisierung aufgerufen werden soll usw. Diese spezifische Persönlichkeitsroutine ist für die Behandlung von C ++ - Ausnahmen vorgesehen (im Gegensatz beispielsweise zu gcj / Java) Ausnahmebehandlung).
quelle
Die Ausnahmebehandlung ist in freistehenden Implementierungen enthalten.
Der Grund dafür ist, dass Sie möglicherweise
gcc
Ihren Code kompilieren. Wenn Sie mit der Option kompilieren, werden-###
Sie feststellen, dass die Linker-Option fehlt,-lstdc++
wenn der Linker-Prozess aufgerufen wird. Das Kompilieren mitg++
enthält diese Bibliothek und damit die darin definierten Symbole.quelle
file.cpp
mitgcc
stattg++
?libstdc++
der einzige Unterschied zwischen den beiden.Ein kurzer Blick auf die
libstd++
Codebasis ergab die folgenden zwei Verwendungen von__gx_personality_v0
:In libsupc ++ / unwind-cxx.h
In libsupc ++ / eh_personality.cc
(Hinweis: Es ist tatsächlich etwas komplizierter. Es gibt eine bedingte Kompilierung, die einige Details ändern kann.)
Solange Ihr Code keine Ausnahmebehandlung verwendet, hat das Definieren des Symbols
void*
keine Auswirkungen, aber sobald dies der Fall ist, stürzen Sie ab -__gxx_personality_v0
ist eine Funktion, kein globales Objekt. Versuchen Sie es also Wenn Sie die Funktion aufrufen, springen Sie zur Adresse 0 und verursachen einen Segfault.quelle
Ich hatte diesen Fehler einmal und fand den Ursprung heraus:
Ich habe einen gcc-Compiler verwendet und meine Datei wurde aufgerufen,
CLIENT.C
obwohl ich ein C-Programm und kein C ++ - Programm ausgeführt habe.gcc erkennt die
.C
Erweiterung als C ++ - Programm und die.c
Erweiterung als C-Programm (achten Sie auf das kleine c und das große C).Also habe ich mein Dateiprogramm umbenannt
CLIENT.c
und es hat funktioniert.quelle
Die obigen Antworten sind richtig: Sie werden bei der Ausnahmebehandlung verwendet. Das Handbuch für GCC Version 6 enthält weitere Informationen (die im Handbuch für Version 7 nicht mehr enthalten sind). Der Fehler kann auftreten, wenn eine externe Funktion verknüpft wird, die - GCC unbekannt - Java-Ausnahmen auslöst.
quelle