システムコールのちょっと深い(!?)基本―OSとユーザプログラムの実行が見えてくる

『Linuxシステムコール基本リファレンス』⁠技術評論社、2018⁠⁠、前付けおよび第1章より。

システムコールsystem callは、OS(カーネル)の持つ機能にアクセスする時に使われるしくみです。LinuxなどのOS上でユーザプログラムが実行される際、さまざまなシステムコールが呼び出され、プログラムの実行が進んでいます。ユーザプログラムの観点で、OSにどのような機能があるか、OSがどのように動いているのかを知りたいと思った際、システムコールを一つ一つ見ていくことで具体的な知識を得ることができます。本記事では、そんなシステムコールのちょっと深い基本へと潜ってみましょう。

一見ほとんど何もしないプログラム。しかし、システム内部は忙しい(!?)

C言語で、終了ステータス0を返す以外は何もしないプログラムを1行にまとめてみると、たとえば、

int main(){return 0;}

のように記述できます。たったこれだけで取り立てて何も起きないように見えますが、OSから見るとプログラム(プロセス)を終了するため、標準でリンクされるC言語のスタートアップファイルcrt1.oなど)や標準Cライブラリ(libc)を経由して、exit系のシステムコールは呼び出されます。

下記の図は、Linuxでgcc(コンパイラ)を使ってコンパイルし、glibc(GNU版libc)とリンクした場合の処理の流れです。細かい部分はOS、コンパイラ、ライブラリによって異なる場合がありますが、ここでのポイントは「ユーザプログラムに直接記述しなくても、main()関数を終了すると暗黙のうちにexit系システムコールが呼び出される」ということです⁠。

図  ほとんど何もしないプログラムで、exit系システムコールが呼ばれる様子
図 ほとんど何もしないプログラムで、<code>exit</code>系システムコールが呼ばれる様子

また、画面にテキストメッセージを出力するだけの簡単なプログラムでは、画面(標準出力等)への出力はファイルアクセスの一種であるためシステムコールが必要で、この場合はwriteのシステムコールが使用されます。

※)
Linux上で実際にどんなシステムコールが呼ばれるかはstraceコマンドで調べることができます。

システムコールは長く役立つ技術知識

システムコールは各種OSの中核近くに位置し、基本部分はそうそう変わらない長く役立つ技術知識です。改めて図をよく眺めてみると、ほとんど何もしていないはずが、実際には極めて複雑な様子であるのが見てとれます。システムコールを知ると、OSのしくみがわかる、プログラム実行の本当の姿を知ることができる、といった点がイメージできるのではないでしょうか。