我正在尝试将更大的应用程序从 x86 移植到 arm cortex a9,但是在交叉编译应用程序时,像 modf 这样的浮点函数会出现奇怪的分段错误,其他 libc++ 函数似乎只是处理错误的浮点数,但不要崩溃(见下文)。
所以我尝试了这个小测试程序,它也可以触发错误。测试程序的输出(见下文)应该证明我的问题。
#include <iostream>
int main(int argc, char *argv[])
{
double x = 80;
double y = 0;
std::cout << x << "\t" << y << std::endl;
return 0;
}
在arm cortex a9上编译:
@tegra$ g++ -Wall test.cpp -o test_nativ
@tegra$ ./test_nativ
80 0
交叉编译
@x86$ arm-cortex_a9-linux-gnueabi-g++ test.cpp -o test_cc
@tegra$ ./test_cc
0 1.47895e-309
使用“-static”链接器选项进行交叉编译。
@x86$ arm-cortex_a9-linux-gnueabi-g++ -static test.cpp -o test_cc_static
@tegra$ ./test_cc_static
80 0
.
@x86$ arm-cortex_a9-linux-gnueabi-objdump -S test_cc
see: http://pastebin.com/3kqHHLgQ
@tegra$ objdump -S test_nativ
see: http://pastebin.com/zK35KL4X
.
回答下面的一些评论:
- 为小端设置了交叉编译器,就像 tegra 机器上的本机编译器一样。
- 我不相信它是内存对齐问题,我在移植到 arm 时分享了这些,这些应该将 SIGBUS 发送到应用程序或记录到 syslog,请参阅 /proc/cpu/alignment 的文档。
我目前的解决方法是复制交叉编译的工具链并将其与 LD_LIBRARY_PATH 一起使用......不太好,但暂时足够好。
编辑:
感谢您的回答。
与此同时,我发现 tegra 设备上的 linux 发行版是使用“-mfloat-abi=softfp”编译的,尽管文档指出,需要使用“-mfloat-abi=hard”编译的工具链。
改变工具链带来了成功。
似乎在任何系统二进制文件上使用“readelf -A”可以看出硬和软文件之间的区别:
如果输出包含以下行:“Tag_ABI_VFP_args: VFP registers”,则使用“-mfloat-abi=hard”编译。如果缺少此行,则二进制文件很可能是使用“-mfloat-abi=softfp”编译的。
'Tag_ABI_HardFP_use: SP and DP' 行并不表示编译器标志 '-mfloat-abi=hard'。