[解決済み] なぜセグメンテーションフォールトは回復できないのですか?
質問
以下 以前の私の質問 のように、ほとんどのコメントで、「とにかくやめてください、手詰まり状態です、すべてを破棄して最初からやり直さなければなりません」と書かれています。 また、次のような安全な回避策もあります。 .
私が理解できないのは なぜ セグメンテーション フォルトは、本質的に回復不可能です。
保護されたメモリへの書き込みが捕捉される瞬間 - そうでない場合は
SIGSEGV
は送信されません。
保護されたメモリへの書き込みの瞬間を捕らえることができるのであれば、なぜ - 理論的には - ある低レベルでそれを元に戻し、SIGSEGV を標準的なソフトウェア例外に変換させることができないのか、私には理解できません。
セグメンテーション フォルトの後、プログラムが未確定の状態にある理由を説明してください。 前に の前に投げられたからです (私はおそらく間違っていて、その理由はわかりません)。もし、フォルトが投げられた後であれば、保護されたメモリを 1 バイトずつ変更するプログラムを作成し、セグメンテーション フォルトを取得し、最終的にカーネルを再プログラムすることができます。
-
セグメンテーション フォルトは正確にいつ発生するのか (= いつが
SIGSEGV
が送信されたとき) ですか? - なぜ、その時点以降、プロセスが未定義の動作状態になっているのでしょうか?
- なぜ回復不能なのですか?
- なぜ この解決策 はその回復不可能な状態を回避するのでしょうか?それもあるのでしょうか?
どのように解決するのですか?
<ブロッククオートセグメンテーションフォールトは、具体的にいつ発生するのでしょうか (= SIGSEGV はいつ送信されるのでしょうか)。
境界外の配列にアクセスしたり、無効なポインタをデリファレンスしたりするなど、アクセス権のないメモリにアクセスしようとしたときです。その際、シグナル
SIGSEGV
Segmentation faultは主に*nix系で使われる用語で、Windowsではaccess violationと呼ばれています。
なぜその時点以降、プロセスが未定義の動作状態になるのでしょうか?
プログラム内の1つまたはいくつかの変数が期待通りに動作しなかったからです。例えば、いくつかの値を格納するはずの配列があったとして、そのすべての値に対して十分な領域を割り当てなかったとします。そのため、割り当てた値だけが正しく書き込まれ、残りの値は配列の枠外に書き込まれ、値を保持することができません。OSは、アプリケーションが機能するために、これらの境界外の値がどれほど重要であるかを正確に知ることができるのでしょうか?OS はその目的について何も知らないのです。
さらに、許可されたメモリの外への書き込みは、しばしば他の無関係な変数を破損する可能性があり、これは明らかに危険で、任意のランダムな動作を引き起こす可能性があります。このようなバグは、しばしば追跡が困難です。たとえば、スタック オーバーフローは、エラーが保護メカニズムによって捕捉されない限り、隣接する変数を上書きしがちな、そのようなセグメンテーション エラーです。
OS も仮想メモリ機能もない、生の物理メモリだけの「ベアメタル」マイクロコントローラ システムの挙動を見ると、たとえば無関係な変数を上書きするなど、言われたとおりに黙々と実行し、そのまま継続します。その結果、アプリケーションがミッションクリティカルである場合には、悲惨な動作を引き起こす可能性があります。
なぜ回復できないのでしょうか?
OSがあなたのプログラムが何をすることになっているのか知らないからです。
上記のベアメタル シナリオでは、システムはセーフ モードに移行して処理を継続するほど賢明である可能性があります。自動車や医療技術などの重要なアプリケーションは、それ自体が危険であるため、単に停止したりリセットしたりすることは許されません。むしろ、制限された機能で家に引きずり戻ろうとするでしょう。
なぜこのソリューションでは、その回復不可能な状態を回避できるのでしょうか?また、そのようなことはないのでしょうか?
その解決策は、エラーを無視して続けているだけです。原因となった問題を解決しているわけではありません。非常に汚いパッチであり、一般的にsetjmp/longjmpは非常に危険な関数なので、いかなる目的でも避けるべきです。
私たちは、セグメンテーションフォールトが 症状 ではなく、バグの 原因 .
関連
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] セグメンテーションフォールトとは何ですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】'cout'は型名ではない
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー