[解決済み] `bash: ./a.out: ld` が生成した実行ファイルを実行する際に、そのようなファイルやディレクトリはありません`。
質問
以下はC言語によるHello Worldのコードです。
// a.c
#include <stdio.h>
int main() {
printf("Hello world\n");
return 0;
}
としてコンパイルしています。
gcc a.c
を生成します。
a.out
は期待通り、そして
./a.out
が印刷されます。
Hello world
... 予想通りです。
今度は、コンパイルとリンクを別々に行うと。
gcc -c a.c; ld -lc a.o
を実行します。
a.out
として生成されます。
./a.out
というメッセージが出ます。
bash: ./a.out: No such file or directory
ググってみたら、生成された実行ファイルが32bitのELFで、マシンのアーキテクチャが64bitの場合にこのエラーが発生するようです。
私は64ビットマシンで
file a.out
が与える。
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
なぜ、このようなことが起こるのでしょうか?
EDIT
の出力
uname -m
$ uname -m
x86_64
の出力
ldd a.out
$ ldd a.out
linux-vdso.so.1 => (0x00007ffeeedfb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa13a7b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa13abab000)
gcc a.c
プロデュース
a.out
であり、正しく実行されます。
解決方法は?
動的実行ファイルを
gcc foo.o
(CRTとlibcに正しいパスを使用し、ダイナミックリンカー/ELFインタープリターに
ld-linux-x86-64.so.2
).
または
gcc -nostartfiles foo.o
libc の場合ですが、CRT ではありません。
_start
があれば、手書きの
_start
(libcやCRTのない静的な実行ファイルの場合は
ld
を直接使用するか
gcc -nostdlib -static
.)
gcc -v foo.o
は、あなたのシステムでGCCが実際に使用したパスを表示します。
他の回答は、これを回避する方法のみを取り上げています 1 ではなく 何が起こったのか、実際の問題 .
は、以下の通りです。
gcc -c a.c; ld -lc a.o
コマンドを使用すると、かなり明白な警告が表示されます。
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400260
ですから、このファイルを実行できたとしても、おそらくすぐにクラッシュしてしまうでしょう。 EmployedRussian さんの回答を見る をご覧ください。
なぜ実行すらできないのかという疑問は、やはり気になるところです。
$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 72 vars */]) = -1 ENOENT (No such file or directory)
execve(2)
は ENOENT を返します。これはインタープリタが見つからないからです(これは
file
など、下記参照)。 で始まるファイルを実行しようとすると、同じエラーが発生します。
#!/usr/non-existant-path/bin/bash
あなたが発見したように、このエラーメッセージの通常の理由は、正しいダイナミックリンカーとダイナミックライブラリがインストールされていないシステム(例:32ビットサポートがインストールされていない64ビットシステム)でELFバイナリを実行したときです。 あなたの場合は、間違ったリンクコマンドを使用し、間違ったインタープリターパスで動的実行ファイルを作成したことが原因です。
私はUbuntu 15.10を使っていますが、そこではGNU
file
バージョン5.22が報告されています。
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld64.so.1, not stripped
はありません。
/lib/ld64.so.1
を実行します。
ldd
の出力は紛らわしいです。
ldd
はバイナリで指定されたものではなく、デフォルトのELFインタープリタを使用します。
$ ldd a.out
linux-vdso.so.1 => (0x00007ffc18d2b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0e0a79f000)
/lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x0000559dbc9d2000)
つまり、バイナリ内のランタイムインタープリタが解決したものと仮定しているのです。
ldd
は自分自身を使ったのでしょう。
あなたの
ldd
と表示されるだけなので、おそらく古いバージョンのものだと思われます。
/lib64/ld-linux-x86-64.so.2
という行があります。 このような奇妙なケースでは、下手な推測をしない方が良い行動かもしれませんが、バイナリのインタープリタパスが奇妙であることを確認する助けにはなりません。
readelf -l a.out
はELFヘッダをデコードし、インタープリタのパスも表示します。 (@EmployedRussian のコメントによる指摘に感謝します)。
関連
-
[解決済み】ENOENTが「そのようなファイルやディレクトリはありません」という意味であるのはなぜですか?
-
[解決済み】fatal error: Python.h: そのようなファイルやディレクトリはありません
-
[解決済み】式は、単純なポインタ演算を使用して完全なオブジェクト型へのポインタでなければなりません【重複】。
-
[解決済み】 error: too few arguments to function `printDay' (C言語)
-
[解決済み] clang: error: linker command failed with exit code 1が表示されるのはなぜですか?
-
[解決済み】エラー:イニシャライザー要素がロード時に計算可能でない
-
[解決済み】C言語で入力が整数型かどうかチェックする
-
[解決済み] C: エラー: ';'トークンの前に ')' があると予想される
-
[解決済み】インクリメントオペランドとして lvalue が必要です。
-
[解決済み] Bashでファイルの中身をループする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Valgrind が "Invalid write of size 8" で文句を言う。
-
[解決済み】変数の警告が設定されているが使用されていない
-
[解決済み】cudamalloc()の使用。) なぜダブルポインタなのか?
-
[解決済み】スレッド1:EXC_BAD_ACCESS(コード=1、アドレス=0x0)標準Cメモリ問題
-
[解決済み】 「配列のイニシャライザーはイニシャライザーリストまたは文字列リテラルでなければなりません」と表示されるのですが?
-
[解決済み】LinuxのI_PUSHに相当するもの
-
[解決済み】スタックスマッシュを検出しました
-
[解決済み] '{'トークンの前に期待される式
-
[解決済み】whileループの時間複雑性(Big O)はどうやったらわかるの?
-
[解決済み] バイナリ実行時に "No such file or directory "エラー発生