大きなアプリケーションを 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;
}
腕の皮質 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 で使用することです...良くありませんが、当分の間は十分です。
編集:
回答ありがとうございます。
その間、ドキュメントには「-mfloat-abi=hard」でコンパイルされたツールチェーンが必要であると記載されていましたが、tegra デバイスの Linux ディストリビューションが「-mfloat-abi=softfp」でコンパイルされていることがわかりました。
ツールチェーンの変更が成功をもたらしました。
hard と softfp の違いは、任意のシステム バイナリで「readelf -A」を使用して確認できるよう
です。この行がない場合、バイナリは「-mfloat-abi=softfp」でコンパイルされている可能性があります。
'Tag_ABI_HardFP_use: SP and DP' という行は、コンパイラ フラグ '-mfloat-abi=hard' を示していません。