什么是__aeabi_unwind_cpp_pr1'我该如何避免呢?

时间:2017-05-26 22:16:29

标签: c++ c gcc

我有一堆手臂组件,C和C ++文件。 gcc正在尝试链接它们,但这些是用于嵌入式项目的。

我没有使用任何外部库,所有正在使用的代码都是由我编写的。似乎发生错误,因为我在int kernel_main(void)中定义了一个名为main.c的函数,该函数试图调用set_LED(int value)中定义的mailbox.cpp,其中包含标题mailbox.h(我确实在main.c文件中包含了标题。)

确切的错误是:

undefined reference to `__aeabi_unwind_cpp_pr1'

我制作项目的方式是: - 将所有源文件(.s,.c,.cpp)编译为目标文件(.o)而不链接(-c),然后使用自定义链接描述文件将它们全部链接在一起。

编辑:我将添加一些信息以使事情更加清晰。

首先更改所有文件,使其全部为C文件(无cpp扩展名),产生:

undefined reference to `set_LED'

问题本身不太可能是名称错误,它可能与CPP和C差异无关。

问题很可能是链接器问题<​​/ p>

这是构建过程:

编译c文件,例如:

arm-none-eabi-g++ -O0 -march=armv8-a source/MainFiles/mailbox.cpp -nostartfiles -c -o objects/MainFiles/mailbox.o

(除了使用g ++而不是gcc之外,编译C ++文件是相同的)

链接一切:

arm-none-eabi-ld object1 object2... -o build/kernel.elf -T ./source/kernel.ld -I include_directory_1 -I include_directory_2 -L include_directory_1 -L indlude_directory_2

包含目录是当前目录下的所有目录

编辑: 错误回来了。忽略与名称重整相关的此问题的部分。我需要解决的错误是:

./objects/Hardware/mailbox.o:(.ARM.exidx+0x18): undefined reference to `__aeabi_unwind_cpp_pr1'

到目前为止,我所知道的是,这与解除堆栈和异常有关。似乎函数是在libgcc中定义的。但是我使用了-nostdlib,我省略了它,并且在这两种情况下错误仍然存​​在。我尽可能地将文件扩展名更改为.c,并尽可能地将.cpp更改为.cpp,总是存在错误。

只有我有1个cpp文件并且我的其余文件都是C文件(这不再是真的,我试过),它才得到修复。再次触发错误的原因是我正在重构代码,我想将一些函数移动到新文件中。

换句话说,在不删除单个文件的情况下,在mailbox.cpp中声明一个名为wait(uint32_t time)的函数可以正常工作,在一个名为time.c(或cpp)的文件中声明它与它的相应头声明并在mailbox.cpp中包含标题会破坏事物。注意我在移动函数时不删除文件我只是删除每个文件中的函数声明。

添加这样的存根:

void __aeabi_unwind_cpp_pr1()
{

}

修复问题并且代码有效。但我不喜欢这个解决方案。我不希望在我的代码中神秘地调用无用的存根。在我当前的实现中,我不需要也不想要这个函数,我怎么能告诉编译器或链接器它们要省略它们正在做什么需要这个函数呢?

4 个答案:

答案 0 :(得分:1)

您有对此函数的引用,该函数属于GCC的C ++运行时。它是异常处理的一部分。无论你做什么,听起来有点疯狂,但无论如何,如果你真的知道自己在做什么,你可以做到这一点。您必须链接到C ++运行时库。就是这样。链接&#34; libstdc ++&#34;。

关于set_LED我也相信它只是关于C ++的修改,正如Justin J在另一个答案中提到的那样。

答案 1 :(得分:1)

混合使用C和C ++时,我已经看到了这一点。由于名称重整,符号将在内部具有不同的名称,具体取决于源文件的类型。

如果'set_LED'的来源是c文件,请在原型的标题中使用以下内容,看看它是否有帮助。

#ifdef __cplusplus
extern "C" {
#endif

// function prototypes here

#ifdef __cplusplus
}
#endif

答案 2 :(得分:1)

解决方案非常简单。事实证明,默认情况下启用了异常(这是生成调用__eabi_unwind_cpp_pr1的代码的原因)。要禁用它们,只需传递: -fno-exceptions作为gcc / g ++编译器的参数,问题解决了。

答案 3 :(得分:-2)

还请添加前缀&#34; -shared&#34;没有-fno-exceptions的引号。我正在使用ARM GCC版本