This is a second-hand question from an OS development site, but it made me curious since I couldn't find a decent explanation anywhere.
When compiling and linking a free-standing C++ program using gcc, sometimes a linker error like this 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 missing in a free-standing environment. Fixing the problem simply requires defining this symbol somewhere:
void *__gxx_personality_v0;
Which is nice, but I don't like things that just magically work... So the question is, what is the purpose of this symbol?
A quick grep of the libstd++
code base revealed the following two usages 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: it's actually a little more complicated than that; there's some conditional compilation that can change some details).
So, as long as your code isn't actually using exception handling, defining the symbol as void*
won't affect anything, but as soon as it does, you're going to crash - __gxx_personality_v0
is a function, not some global object, so trying to call the function is going to jump to address 0 and cause a segfault.
It's part of the exception handling. The gcc EH mechanism allows to mix various EH models, and a personality routine is invoked to determine if an exception match, what finalization to invoke, etc. This specific personality routine is for C++ exception handling (as opposed to, say, gcj/Java exception handling).
Exception handling is included in free standing implementations.
The reason of this is that you possibly use gcc
to compile your code. If you compile with the option -###
you will notice it is missing the linker-option -lstdc++
when it invokes the linker process . Compiling with g++
will include that library, and thus the symbols defined in it.
I had this error once and I found out the origin:
I was using a gcc compiler and my file was called CLIENT.C
despite I was doing a C program and not a C++ program.
gcc recognizes the .C
extension as C++ program and .c
extension as C program (be careful to the small c and big C).
So I renamed my file CLIENT.c
program and it worked.
A quick grep of the libstd++
code base revealed the following two usages 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: it's actually a little more complicated than that; there's some conditional compilation that can change some details).
So, as long as your code isn't actually using exception handling, defining the symbol as void*
won't affect anything, but as soon as it does, you're going to crash - __gxx_personality_v0
is a function, not some global object, so trying to call the function is going to jump to address 0 and cause a segfault.
Exception handling is included in free standing implementations.
The reason of this is that you possibly use gcc
to compile your code. If you compile with the option -###
you will notice it is missing the linker-option -lstdc++
when it invokes the linker process . Compiling with g++
will include that library, and thus the symbols defined in it.
It's part of the exception handling. The gcc EH mechanism allows to mix various EH models, and a personality routine is invoked to determine if an exception match, what finalization to invoke, etc. This specific personality routine is for C++ exception handling (as opposed to, say, gcj/Java exception handling).
The answers above are correct: it is used in exception handling. The manual for GCC version 6 has more information (which is no longer present in the version 7 manual). The error can arise when linking an external function that - unknown to GCC - throws Java exceptions.
It's part of the exception handling. The gcc EH mechanism allows to mix various EH models, and a personality routine is invoked to determine if an exception match, what finalization to invoke, etc. This specific personality routine is for C++ exception handling (as opposed to, say, gcj/Java exception handling).
Exception handling is included in free standing implementations.
The reason of this is that you possibly use gcc
to compile your code. If you compile with the option -###
you will notice it is missing the linker-option -lstdc++
when it invokes the linker process . Compiling with g++
will include that library, and thus the symbols defined in it.
I had this error once and I found out the origin:
I was using a gcc compiler and my file was called CLIENT.C
despite I was doing a C program and not a C++ program.
gcc recognizes the .C
extension as C++ program and .c
extension as C program (be careful to the small c and big C).
So I renamed my file CLIENT.c
program and it worked.
The answers above are correct: it is used in exception handling. The manual for GCC version 6 has more information (which is no longer present in the version 7 manual). The error can arise when linking an external function that - unknown to GCC - throws Java exceptions.
A quick grep of the libstd++
code base revealed the following two usages 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: it's actually a little more complicated than that; there's some conditional compilation that can change some details).
So, as long as your code isn't actually using exception handling, defining the symbol as void*
won't affect anything, but as soon as it does, you're going to crash - __gxx_personality_v0
is a function, not some global object, so trying to call the function is going to jump to address 0 and cause a segfault.
It's part of the exception handling. The gcc EH mechanism allows to mix various EH models, and a personality routine is invoked to determine if an exception match, what finalization to invoke, etc. This specific personality routine is for C++ exception handling (as opposed to, say, gcj/Java exception handling).
Source: Stackoverflow.com