Gccを使用してプログラムをコンパイルし、それをbashシェルから実行しようとすると、それを実行するためにbashが実行する正確な手順は何ですか?
知っているfork()
、execve()
、loader
、dynamic linker
(およびその他のもの)が関係しますが、誰かが正確な一連のステップと適切な読み取りリファレンスを提供できますか?
編集:
答えから、質問は多くの可能性を暗示することができるようです。単純なケースに絞り込みたい:
(test.cはhello worldを出力するだけです)
$ gcc test.c -o test
$ ./test
上記の場合の手順は何ですか(./test
)、特にいくつかの子プロセスでのbash起動プログラムの関連付け、ロード、リンクなどの実行?
まあ、実際のプログラムが実行される前に最初に展開/解釈されるシェルのエイリアスまたは関数があり、次に修飾されたファイル名(_/usr/libexec/foo
_)と見られるものの違いがあるため、正確なシーケンスは異なる場合があります。 PATH
環境変数のすべてのディレクトリ(foo
のみ)を使用します。また、_foo | bar | zot
_はシェルにいくつかの作業が必要になるため、実行の詳細が問題を複雑にする可能性があります(いくつかのfork(2)
、dup(2)
、およびもちろんpipe(2)
ですが、_exec foo
_のようなものは、シェルが新しいプログラムに置き換えられるだけです(つまり、fork
ではありません)。プロセスグループも重要です(特にフォアグラウンドプロセスグループ。すべてのPIDは、誰かがマッシュアップを開始したときにSIGINT
を食べます) Ctrl+C、セッション、およびジョブがバックグラウンドで実行されるか、監視されるか(_foo &
_)またはバックグラウンド、無視されるか(_foo & disown
_)。 I/Oリダイレクションの詳細は、たとえば、標準入力がシェルによって閉じられた場合(_foo <&-
_)、またはファイルがstdinとして開かれたかどうか(_foo < blah
_)も変更します。
strace
または同様のものは、このプロセスに沿って行われた特定のシステムコールについての情報を提供し、それらの各コールのマニュアルページが存在する必要があります。適切なシステムレベルの読み取りは、Stevensの「UNIX環境での高度なプログラミング」からの任意の数の章になりますが、シェルブック(たとえば、「BashからZシェルへ」)は、シェルの側面をより詳細にカバーします。
(動的リンカーが実行されるように)既に実行されている(コードを明確にするための)教科書の例のシェルを想定すると、言及するコマンドは、シェルが次のシステムコールを行うことを要求します。
もちろん、より複雑なコマンドを使用すると、この基本的なシーケンスがさらに複雑になります。基本的な複雑化の2つのより単純な例は、オープン、クローズ、DUPシーケンスがフォークとexecの間に挿入される基本的なioリダイレクションと、待機がスキップされる(そして別の待機がsigchldハンドラーに追加される)バックグラウンドプロセスです。
セクションを読むことをお勧めします8.4.6 forkとexecveを使用してプログラムを実行する
on http://www.groupes.polymtl.ca/inf2610/documentation/ComputerSystemBook.pdf