これは実装の質問ではなくデザインですセグメンテーションを送信する代わりにシステムコールがEFAULTを返すのはなぜですか?
POSIXがこのように動作する理由の根本を知りたいと思います。無効なメモリ位置が与えられたときのPOSIXシステムコールは、(sigsegvを送ることによって)ユーザ空間プログラムをクラッシュさせるのではなく、EFAULTを返します。
なぜですか?これはちょうどメモリのバグを隠していませんか?それは歴史的な間違いですか、それともそれには正当な理由がありますか?
これは実装の質問ではなくデザインですセグメンテーションを送信する代わりにシステムコールがEFAULTを返すのはなぜですか?
POSIXがこのように動作する理由の根本を知りたいと思います。無効なメモリ位置が与えられたときのPOSIXシステムコールは、(sigsegvを送ることによって)ユーザ空間プログラムをクラッシュさせるのではなく、EFAULTを返します。
なぜですか?これはちょうどメモリのバグを隠していませんか?それは歴史的な間違いですか、それともそれには正当な理由がありますか?
システムコールはユーザプログラムではなくカーネルによって実行されるため、システムコールが発生するとユーザプロセスは停止し、カーネルが終了するのを待ちます。
もちろん、カーネル自体はフォールトを断つことができないため、ユーザープロセスが提供するすべてのアドレス領域を手動でチェックする必要があります。これらのチェックの1つが失敗すると、システムコールはEFAULT
で失敗します。したがって、この状況では、セグメンテーションフォルトは実際には起こっていません。すべてのアドレスが有効であることをカーネルが明示的にチェックすることによって回避されています。したがって、信号が送信されないことは意味をなさない。
さらに、信号がに送信された場合、カーネルがシグナルに意味のあるプログラムカウンタを付けることはできません。システムコールの実行中にユーザープロセスが実際に実行されません。これは、ユーザープロセスがまともな診断を生成し、失敗した命令を再起動する方法がないことを意味します。
要約すると:主に歴史的ですが、推論には実際のロジックがあります。 EINTR
のように、これで対処するのがそれほど難しくありません。
「意味のあるプログラムカウンタを信号に付ける」とはどういう意味ですか?ユーザーのシグナルハンドラが実行された後、どこから再開するのかわからないということでしょうか?システムコールの直後ではないでしょうか? –
はい、再開についてのビットを無視してください---もう少し考えてみてください。実際には関係ありません。 (なぜなら、カーネルがsegフォールトを起こすと、それは容易にレジスタ状態を偽造するからです。)ここでの主な問題は、カーネルはあなたにsegフォルトを送信していないと思います。 –
あなたはどうでしょうかが欲しいですか?システムコールは、システムに対する要求です。あなたが尋ねるなら: "ミュンヘンへのフェリーはいつ出発するのですか?"プログラムがクラッシュしたり、errno = ENOHARBORでreturn = -1を取得したいですか?あなたがあなたのハンドバッグにあなたの車を置くようにシステムに頼んだら、あなたのハンドバッグを破壊したいですか、またはerrnoをEBAGTOOSMALLに設定して-1を返しますか?
技術的な詳細があります:syscallsの前後に、システムコールに出入りするときにuser/system -landとの引数を変換(コピー)する必要があります。主にセキュリティ上の理由から、システムはユーザー空間に書き込むことを非常に嫌っています。 (Linuxはcopy_to_user_space関数を持っています(その逆もあります)。の前にが実際のコピーをしています)
私はすでに、アプリにsegfaultシグナルを送信することで、より意味をなさされると言います。 –
ああ、私はあなたの質問を誤解しているかもしれません。copyfromuser()、copytouser()(Linuxの場合)はカーネルモードから実行されるので、カーネルによって "手動で"実行されなければならず、SEGVEは可能ではなく、カーネル*あなたのためにこのコピーを実行することができます。正式には、セグメンテーション違反ではありません(ユーザー空間から実行された場合は*)。また、ユーザープロセスのビューから、システムコールは戻り値を持つ関数に過ぎません。信号は、いくつかの非同期事象を表すものとする。 – wildplasser
私にはsigsegv/sigbusも意味があります。今私は、(より遅い)ユーザ空間のエミュレーションを持つべき2つのカスタムシステムコールで遊んでいます。無効なバッファを渡した場合、実際のシステムコールとエミュレーションが異なる動作をする理由がわかりません。 POSIXでも、システム関数が実際のシステムコールかユーザスペース関数かどうかを気にするべきではないと判断されているようです。関連する質問:https://stackoverflow.com/questions/44239545/generating-segfault-from-a-custom-syscall/44251112 – PSkocik