3

次のコマンドを使用して、Linux on Ubuntu 5.4 (GNAT 3.4) 用の Ada プログラムをコンパイルしました。

gnatmake -O3 myprogram -bargs -static

その後、Ubuntu マシンでプログラムを実行すると、正常に動作します。しかし、別のマシン (Linux Web サーバー) で試してみると、次のエラー メッセージが表示されますstrace

execve("./myprogram", ["./myprogram"], [/* 15 vars */]) = 0
brk(0)                                  = 0x811e000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f8000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f7000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb76f7680, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

どういう意味ですか?2 つのファイル (ld.so.nohwcap と ld.so.preload) が不足しているため、プログラムを実行できないということは正しく理解できていますか? このエラーを回避するにはどうすればよいですか? コンパイル中にこれらのファイルをプログラムに含める可能性はありますか?

4

3 に答える 3

4

どういう意味ですか?

NULLこれは、プログラムがポインターを逆参照しようとして、終了したことを意味しますSIGSEGV

2 つのファイル (ld.so.nohwcap と ld.so.preload) が不足しているため、プログラムを実行できないということは正しく理解できていますか?

いいえ: これらのファイルが存在しないのは完全に正常であり、問​​題はそれらとは何の関係もありません。

  1. このような問題をデバッグするツールはgdb. straceこのようなデバッグに役立つことはめったにありません。
  2. 一般に信じられていることとは反対に、完全に静的な実行可能ファイル (作成したもの) はLinux では移植性が低く、動的にリンクされたものよりも移植性が低くなります。特に、リンク時に次のような警告が表示される可能性があります。

    Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

    その場合、ビルド マシンと Web サーバー マシンにインストールされている glibc のバージョンが異なる場合、それがまさにあなたの問題です。このような警告を無視しないでください (また、実行可能ファイルを-staticフラグ付きでリンクしないでください)。

アップデート:

不足している libgnat だけをプログラムに含めることはできますか?

可能かもしれません: あなたがしたいことは、最終的なリンク行が次のようになるように調整することです:

gcc ... -Wl,-Bstatic -lgnat -Wl,-Bdynamic ...

でそれを達成する方法がわかりませんgnatmake

別の、おそらくもっと単純な代替案: サーバーへのインストールを検討しlibgnat-3.4.so.1たことがありますか?

于 2012-04-12T04:01:37.853 に答える
2

strace から表示される出力は、ライブラリにリンクしようとしているダイナミック リンカーです。

  1. lddを実行することをお勧めします。これにより、依存関係が表示されます
  2. それが機能しない場合は、依存関係を修正します
  3. 再コンパイルする場合は、-g フラグを使用して後でデバッグします
  4. まだ実行されていない場合は、gdb を使用して実行します。

補足: CPU が「まったく」同じであることを常に確認してください。それ以外の場合は、新しいマシンで再コンパイルし、実行可能ファイルをバイナリとして転送してください。

読んでよかったマニュアルページ

于 2012-04-12T04:57:01.930 に答える