__gxx_personality_v0 有什么用?

2021-12-18 00:00:00 gcc kernel linker c++

这是一个来自操作系统开发站点的二手问题,但它让我很好奇,因为我在任何地方都找不到合适的解释.

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.

在使用 gcc 编译和链接一个独立的 C++ 程序时,有时会出现这样的链接器错误:

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'

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

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?

推荐答案

它用于堆栈展开表,例如您可以在 我对另一个问题的回答.如该答案所述,它的使用由 Itanium C++ ABI 定义,其中它被称为个性程序.

It is used in the stack unwiding tables, which you can see for instance in the assembly output of my answer to another question. As mentioned on that answer, its use is defined by the Itanium C++ ABI, where it is called the Personality Routine.

通过将其定义为全局 NULL void 指针来工作"的原因可能是因为没有任何内容引发异常.当某些东西试图抛出异常时,你会看到它行为不端.

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

当然,如果没有使用异常,您可以使用 -fno-exceptions 禁用它们(如果没有使用 RTTI,您也可以添加 -fno-rtti>).如果您正在使用它们,则必须(正如其他答案已经指出的那样)使用 g++ 而不是 gcc 链接,这将添加 -lstdc++你.

Of course, if nothing is using exceptions, you can disable them with -fno-exceptions (and if nothing is using RTTI, you can also add -fno-rtti). If you are using them, you have to (as other answers already noted) link with g++ instead of gcc, which will add -lstdc++ for you.

相关文章