102 votes

Ce qui est __gxx_personality_v0 pour ?

C'est une seconde main de la question à partir d'un OS de développement du site, mais il m'a rendu curieux puisque je ne pouvais pas trouver une explication décente n'importe où.

Lors de la compilation et la liaison d'un libre-debout programme en C++ avec gcc, parfois, une erreur d'éditeur de liens comme cela se produit:

out/kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'

Ce est apparemment parce que ce symbole est défini dans la bibliothèque libstdc++, ce qui est manquant dans un environnement. La résolution du problème nécessite simplement de la définition de ce symbole quelque part:

void *__gxx_personality_v0;

Ce qui est agréable, mais je n'aime pas les choses qui fonctionne par magie... la question est Donc, quel est le but de ce symbole?

91voto

CesarB Points 18048

Il est utilisé dans la pile unwiding tables, que vous pouvez voir, par exemple, dans l'assemblée de sortie de ma réponse à une autre question. Comme mentionné sur cette réponse, son utilisation est définie par l' Itanium ABI C++ , où il est appelé la Personnalité de Routine.

La raison pour laquelle il "fonctionne" en le définissant comme un global nulle NULLE pointeur est probablement parce que rien n'est à jeter une exception. Quand quelque chose essaie de lancer une exception, alors vous verrez qu'il se comporte mal.

Bien sûr, si rien n'est l'utilisation d'exceptions, vous pouvez les désactiver avec -fno-exceptions (et si rien n'est à l'aide de RTTI, vous pouvez également ajouter des -fno-rtti). Si vous les utilisez, vous devez (comme d'autres réponses déjà noté) lien avec g++ au lieu de gcc, -lstdc++ pour vous.

12voto

Martin v. Löwis Points 61768

Cela fait partie de la gestion des exceptions. Le mécanisme EH gcc permet de mélanger les différents modèles EH et une routine de personnalité est appelée pour déterminer si un match d’exception, ce que finalisation à invoquer, etc.. Cette routine de personnalité spécifique est pour la gestion des exceptions C++ (par opposition à, disons, exception de gcj/Java manipulation).

11voto

Gestion des exceptions est incluse dans les implémentations autoportante.

La raison de ceci est que vous utilisez peut-être pour compiler votre code. Si vous compilez avec l’option , vous remarquerez qu’il manque l’option- quand il appelle le processus de l’éditeur de liens. Compilation avec comprendra que la bibliothèque et donc les symboles définis en lui.

6voto

Adam Rosenfield Points 176408

Un rapide grep de l' libstd++ code de base a révélé que deux usages de l' __gx_personality_v0:

Dans libsupc++/détendez-cxx.h

// GNU C++ personality routine, Version 0.                                      
extern "C" _Unwind_Reason_Code __gxx_personality_v0
     (int, _Unwind_Action, _Unwind_Exception_Class,
      struct _Unwind_Exception *, struct _Unwind_Context *);

Dans libsupc++/eh_personality.cc

#define PERSONALITY_FUNCTION    __gxx_personality_v0
extern "C" _Unwind_Reason_Code
PERSONALITY_FUNCTION (int version,
                      _Unwind_Action actions,
                      _Unwind_Exception_Class exception_class,
                      struct _Unwind_Exception *ue_header,
                      struct _Unwind_Context *context)
{
  // ... code to handle exceptions and stuff ...
}

(Note: en fait c'est un peu plus compliqué que cela; il y a un peu de compilation conditionnelle qui peut changer certains détails).

Ainsi, tant que votre code n'est pas fait usage de la gestion des exceptions, la définition du symbole void* n'affecte en rien, mais dès qu'il fait, vous allez à des crash - __gxx_personality_v0 est une fonction, pas un objet global, afin d'essayer d'appeler la fonction va sauter à l'adresse 0 et de provoquer une erreur de segmentation.

6voto

jlguenego Points 35

J’ai eu cette erreur une fois et j’ai découvert l’origine :

J’ai été en utilisant un compilateur gcc et mon dossier a été appelé `` malgré que je faisais un programme en C et pas un programme C++.

GCC reconnaît la extension en tant que programme C++ et extension en tant que programme C (faire attention à la petite C c et grosse).

Donc j’ai renommé mon fichier `` programme et cela a fonctionné.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X