什么是__gxx_personality_v0?

时间:2008-11-30 16:53:22

标签: c++ gcc linker kernel

这是来自操作系统开发网站的二手问题,但它让我很好奇,因为我无法在任何地方找到合适的解释。

使用gcc编译和链接独立的C ++程序时,有时会发生这样的链接器错误:

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

这显然是因为此符号在libstdc ++中定义,在独立环境中缺失。解决问题只需要在某处定义此符号:

void *__gxx_personality_v0;

哪个好,但我不喜欢那些神奇地工作的东西......所以问题是,这个符号的目的是什么?

6 个答案:

答案 0 :(得分:87)

它用于堆栈展开表,您可以在my answer to another question的汇编输出中看到它。如该答案中所述,其使用由Itanium C++ ABI定义,称为Personality Routine

它通过将其定义为全局NULL void指针而“工作”的原因可能是因为没有任何东西抛出异常。当某些东西试图抛出异常时,你会发现它行为异常。

当然,如果没有使用异常,您可以使用-fno-exceptions禁用它们(如果没有使用RTTI,您也可以添加-fno-rtti)。如果您使用它们,则必须(如已注明的其他答案)与g++而不是gcc相关联,这将为您添加-lstdc++

答案 1 :(得分:10)

这是异常处理的一部分。 gcc EH机制允许混合各种EH模型,并调用个性例程来确定异常是否匹配,要调用的终结等等。这个特定的个性例程用于C ++异常处理(与gcj / Java相反)异常处理)。

答案 2 :(得分:10)

异常处理包含在独立实现中。

这样做的原因是您可能使用gcc来编译代码。如果使用选项-###进行编译,则会在调用链接器进程时发现它缺少linker-option -lstdc++。使用g++进行编译将包括该库,从而包含在其中定义的符号。

答案 3 :(得分:5)

libstd++代码库的快速grep显示以下两个__gx_personality_v0用法:

在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 *);

在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 ...
}

(注意:它实际上比这复杂一点;有一些条件编译可以改变一些细节。)

因此,只要您的代码实际上没有使用异常处理,将符号定义为void*就不会影响任何内容,但只要它发生,您就会崩溃 - {{1是一个函数,而不是一些全局对象,所以试图调用该函数将跳转到地址0并导致段错误。

答案 4 :(得分:5)

我有一次这个错误,我发现了原点:

我使用的是gcc编译器,我的文件名为CLIENT.C,尽管我正在编写C程序而不是C ++程序。

gcc将.C扩展名识别为C ++程序,将.c扩展名识别为C程序(小心c和大C)。

所以我重命名了我的文件CLIENT.c程序并且它有效。

答案 5 :(得分:2)

上面的答案是正确的:它用于异常处理。 GCC版本6的manual有更多信息(版本7手册中不再提供)。链接外部函数时会出现错误 - 未知GCC - 抛出Java异常。