What is __gxx_personality_v0 for?

This is a second-hand question from the OS development site, but I was curious because I could not find a decent explanation anywhere.

When compiling and linking a stand-alone C ++ program using gcc, sometimes such a linker error occurs:

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

This is apparently because this symbol is defined in libstdC ++, which is not available in a free-standing environment. Fixing the problem simply requires defining this symbol somewhere:

 void *__gxx_personality_v0; 

This is good, but I don’t like things that just magically work ... So, the question is, what is the purpose of this symbol?

+79
c ++ gcc linker kernel
Nov 30 '08 at 16:53
source share
6 answers

It is used in nonoverlapping tables, which you can see, for example, in the assembly of my answer to another question . As mentioned in this answer, its use is determined by Itanium C ++ ABI , where it is called "Personality" .

The reason it "works" by defining it as a global pointer is void NULL, probably because nothing throws an exception. When something tries to throw an exception, you will see that it is erroneous.

Of course, if nothing uses exceptions, you can disable them with -fno-exceptions (and if nothing is used by RTTI, you can also add -fno-rtti ). If you use them, you should (as already noted, other answers) refer to g++ instead of gcc , which will add -lstdc++ for you.

+73
Nov 30 '08 at 19:00
source share

This is part of exception handling. The gcc EH mechanism allows you to mix different EH models, and an individual procedure is called to determine if the match matches, which final procedure to call, etc. This is a specific routine for handling C ++ exceptions (unlike, say, gcj / Java exception handling).

+10
Nov 30 '08 at 17:27
source share

Exception handling is included in free-standing implementations.

The reason for this is that you can use gcc to compile the code. If you compile with the option -### , you will notice that the -lstdc++ linker is -lstdc++ when it invokes the linker process. Compiling with g++ will include this library and, therefore, the characters defined in it.

+8
Nov 30 '08 at 18:28
source share

The quick grep of the libstd++ code base showed the following two uses of __gx_personality_v0 :

In libsupC ++ / unwind-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 *); 

In 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: this is actually a little more complicated than this, there is conditional compilation that can change some details).

So, until your code actually uses exception handling, defining a character as void* will not affect anything, but as soon as this happens, you are going to crash - __gxx_personality_v0 is a function, not some global object, so trying to call a function will go to address 0 and call segfault.

+4
Nov 30 '08 at 17:35
source share

I had this error once, and I recognized the origin:

I used the gcc compiler and my file was called CLIENT.C , despite the fact that I was running a C program and not a C ++ program.

gcc recognizes the .C extension as a C ++ program and the .C extension as a C program (be careful with small c and large C).

So, I renamed my CLIENT.C program and worked.

+4
Jul 16 '14 at 7:36
source share

The answers are correct: it is used in exception handling. The GCC version 6 manual contains additional information (which is no longer present in the version 7 manual). An error can occur when binding an external function that - unknown to GCC - throws Java exceptions.

+1
Mar 03 '18 at 21:42
source share



All Articles