À quoi sert GXX personality v0?

c'est une question de seconde main d'un site de développement OS, mais cela m'a rendu curieux car je n'ai pas pu trouver une explication décente nulle part.

lors de la compilation et de la liaison d'un programme C++ autonome en utilisant gcc, parfois une erreur de linker comme celle-ci se produit:

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

c'est apparemment parce que ce symbole est défini dans libstdc++, qui est absent dans un environnement autonome. Pour résoudre le problème, il suffit de définir ce symbole quelque part:

void *__gxx_personality_v0;

ce qui est bien, mais je n'aime pas les choses qui fonctionnent comme par magie... La question est donc, quel est le but de ce symbole?

84
demandé sur Bruce Johnston 2008-11-30 19:53:21

7 réponses

il est utilisé dans la pile des tables déroulantes, que vous pouvez voir par exemple dans la sortie d'assemblage de ma réponse à une autre question . Comme mentionné sur cette réponse , son utilisation est définie par le Itanium C++ ABI , où il est appelé le Routine de personnalité .

la raison pour laquelle il" fonctionne " en le définissant comme un pointeur de vide global est probablement parce que rien ne jette une exception. Lorsque quelque chose essaie de lancer une exception, alors vous verrez qu'il se comporte mal.

bien sûr, si rien n'utilise d'exceptions, vous pouvez les désactiver avec -fno-exceptions (et si rien n'utilise RTTI, vous pouvez aussi ajouter -fno-rtti ). Si vous les utilisez, vous devez (comme d'autres réponses déjà notées) établir un lien avec g++ au lieu de gcc , qui ajoutera -lstdc++ pour vous.

79
répondu CesarB 2017-08-20 18:58:24

ça fait partie de la manipulation d'exception. Le mécanisme EH du gcc permet de mélanger divers modèles EH, et une routine de personnalité est invoquée pour déterminer si une exception correspond, quelle finalisation invoquer, etc. Cette routine de personnalité spécifique est destinée à la gestion des exceptions C++ (par opposition, par exemple, à la gestion des exceptions gcj/Java).

10
répondu Martin v. Löwis 2008-11-30 17:27:27
La gestion des exceptions

est incluse dans les implémentations libres.

la raison en est que vous pouvez utiliser gcc pour compiler votre code. Si vous compilez avec l'option -### , vous remarquerez qu'il manque l'option -lstdc++ quand elle invoque le processus de linker . Compiler avec g++ inclura cette bibliothèque, et donc les symboles définis dans elle.

9
répondu Johannes Schaub - litb 2008-11-30 18:35:39

un grep rapide de la base de code libstd++ a révélé les deux usages suivants de __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: c'est en fait un peu plus compliqué que cela; il y a une compilation conditionnelle qui peut changer certains détails).

donc, tant que votre code n'utilise pas la gestion des exceptions, définir le symbole comme void* n'affectera rien, mais dès qu'il le fera, vous allez vous écraser - __gxx_personality_v0 est une fonction, pas un objet global, donc essayer d'appeler la fonction va sauter à l'adresse 0 et causer un segfault.

5
répondu Adam Rosenfield 2008-11-30 17:35:59

j'ai eu cette erreur une fois et j'ai trouvé l'origine:

j'utilisais un compilateur gcc et mon fichier s'appelait CLIENT.C malgré que je faisais un programme C et non un programme c++.

gcc reconnaît l'extension .C comme programme C++ et l'extension .c comme programme C (attention au petit c et au Grand C).

alors j'ai renommé mon programme CLIENT.c et ça a marché.

5
répondu jlguenego 2014-07-16 07:36:57

Les réponses ci-dessus sont correctes: il est utilisé dans le traitement d'exception. Le manuel pour GCC version 6 a plus d'informations (qui n'est plus présent dans la version 7 manuel). L'erreur peut survenir lors de la connexion d'une fonction externe qui - inconnue de GCC - envoie des exceptions Java.

1
répondu sagitta 2018-03-03 21:42:03

pour ceux qui sont venus ici principalement parce qu'ils ont vu le message d'erreur mais ne comprennent pas tout le reste comme moi. Ce n'est peut-être pas votre solution si vous voulez réellement faire un "programme C++ autonome".

ce qui m'a aidé à résoudre toutes les erreurs de points d'entrée a été de mettre dans la" libstdc++-6.dll " de votre dossier compilateur comme MinGW à côté de votre exe compilé.

cela a également résolu les problèmes de point d'entrée de placer une chaîne std::.

0
répondu RIJIK 2018-10-02 11:03:28