7

SYS_exit、sys_exit()、および exit() の違いは何ですか?

私が理解していること:

  • Linux カーネルは、 にリストされているシステム コールを提供しますman 2 syscalls
  • によって提供されるシステムコールのラッパー関数があり、それらglibcはほとんどシステムコールと似た名前を持っています。

私の質問: ではman 2 syscalls、たとえば SYS_exit と sys_exit() についての言及はありません。彼らは何ですか?

注 :exitここでの syscall は単なる例です。私の質問は本当に: SYS_xxx と sys_xxx() とは何ですか?

4

2 に答える 2

3

これはすべてのシステムコールに適用されますが、例のように exit() を使用します。

sys_exit() 形式の関数は、exit() と考えられる関数を実装するカーネル ルーチンへの実際のエントリ ポイントです。これらのシンボルは、ユーザーモードのプログラマーも利用できません。つまり、カーネルをハッキングしていない限り、これらの関数にリンクすることはできません。これらの関数のシンボルはカーネルの外では使用できないためです。次のようなファイルスコープ機能を持つ libmsw.a を書いた場合

static int msw_func() {}

定義されている場合、libmsw シンボル テーブルにエクスポートされていないため、リンクしようとしても成功しません。あれは:

cc your_program.c libmsw.a

次のようなエラーが発生します。

ld: cannot resolve symbol msw_func

エクスポートされていないためです。カーネルに含まれている sys_exit() にも同じことが当てはまります。

ユーザー プログラムがカーネル ルーチンに到達するには、syscall(2) インターフェイスを使用して、ユーザー モードからカーネル モードへの切り替えを行う必要があります。そのモード切り替え (トラップと呼ばれることもあります) が発生すると、小さな整数を使用して、整数をカーネル関数にマップするカーネル テーブル内の適切なカーネル ルーチンを検索します。テーブルのエントリの形式は次のとおりです。

{SYS_exit, sys_exit},

SYS_exit はプリプロセッサ マクロで、

#define SYS_exit (1)

変更する理由がないため、生まれる前から 1 です。また、単純な配列インデックスを検索するシステム コールのテーブルの最初のエントリでもあります。

質問で指摘したように、通常のユーザーモード プログラムが sys_exit にアクセスする適切な方法は、glibc (または同様のコア ライブラリ) のシン ラッパーを使用することです。SYS_exit や sys_exit をいじる必要がある唯一の理由は、カーネル コードを書いている場合です。

于 2013-09-24T05:50:24.673 に答える