セグメンテーション違反とは何ですか?
セグメンテーション違反 または アクセス違反 ( セグメンテーション違反 簡単に言えば) は、メモリ保護を備えたハードウェアによって発生する障害状態または障害であり、ソフトウェアが制限されたメモリ領域にアクセスしようとした (メモリ アクセス違反) ことをオペレーティング システムに警告します。
これは、標準の x86 システムにおける一般的な保護違反形式です。これに応じて、オペレーティング システムのカーネルは通常、いくつかの修正操作を実装し、通常はプロセスにシグナルを転送することでその障害を問題のプロセスに渡します。
場合によっては、プロセスがシグナル ハンドラーをインストールしてプロセスが独自に回復できるようにすることもできますが、それ以外の場合はオペレーティング システムのデフォルトのシグナル ハンドラーが使用されるため、通常はプロセスが異常終了し、場合によってはコア ダンプが発生します。
- セグメンテーション違反は、次のような多くの言語で指定されたプログラムの基本的なエラー クラスです。 C 低レベルのメモリアクセスを提供し、安全性チェックを知るための言語。
- 主に、仮想メモリのアドレス指定に使用されるポインタの多くのエラー、特に不正アクセスが原因で発生します。
- 他のタイプのメモリ アクセス フォールトは次のとおりです。 バスエラー 、これにはいくつかの原因も含まれます。
- これらは主に、不正確な物理メモリ アドレス指定またはメモリ アクセスの不整合が原因で発生します。
- これらは、プロセスがアドレス指定することを許可されていない参照ではなく、ハードウェアがアドレス指定できない一部のメモリ参照です。
- いくつかのプログラミング言語は、セグメンテーション違反を回避し、メモリの安全性を開発するために作成されたメカニズムを適用する場合があります。 例えば、 の さび プログラミング言語は、メモリの安全性を確保するために所有権ベースのモデルを適用します。別の言語のようなもの ジャワ そして 舌足らずの発音 ガベージ コレクションを適用します。これにより、セグメンテーション フォールトの原因となる可能性のある多くのメモリ エラー クラスが無視されます。
セグメンテーション違反の概要
- セグメンテーション違反は、プログラムがアクセスが許可されていないメモリ位置にアクセスしようとした場合、または許可されていない方法でメモリ位置にアクセスしようとした場合 (たとえば、読み取り専用の場所への書き込みや、ファイルの上書きを試みた場合) に発生します。オペレーティングシステム部分)。
- コンピューティングにおけるこの言葉は、 'セグメンテーション' にはいくつかの用途があります。 1950 年以来使用されている言葉であるセグメンテーション フォールトの方法で、プログラムのアドレス空間を定義します。メモリ保護によりプログラムのアドレス空間のみが読み取り可能であり、このうちスタックとデータ セグメントの読み取り/書き込み部分のみが読み取り可能です。プログラムの書き込みが可能です。したがって、プログラムのアドレス空間の外で読み取りを試みたり、アドレス空間の読み取り専用部分に書き込みを試みたりすると、セグメンテーション違反が発生します。
- セグメンテーション フォールトは、存在しないセグメント、セグメント境界の外側の場所、またはメモリ セグメンテーションを使用するシステム上のセグメントに付与されたアクセス許可で許可されていないスタイルの場所を参照しようとする試みをハードウェアが検出した場合に発生します。仮想メモリを提供するためのハードウェア。
- 一般に、無効なページ フォールトは、ページングのみを使用するシステムでセグメンテーション フォールトを引き起こします。ページフォールトとセグメンテーションフォールトは、どちらも仮想メモリ管理システムに起因するフォールトです。また、セグメンテーション フォールトはページ フォールトとは独立して発生する可能性があります。有効なページへの不正アクセスはセグメンテーション違反です。セグメンテーション違反はページの中央に現れることがあります。内側 バッファオーバーフロー ページ内に存在するが、たとえばメモリを不正に上書きするもの。
- まず、障害の原因は次のとおりです。 MMU ( メモリ管理ユニット ) メモリ保護の側面のセグメントとしての不正アクセス、またはハードウェア レベルでの無効なページ フォールト。問題が無効な論理アドレスではなく、無効な物理アドレスである場合は、むしろバス エラーが発生します。したがって、これらは必ずしも区別されるわけではありません。
- この障害が検出されると、問題のプロセスにシグナルが送信され、オペレーティング システム レベルでそのシグナルに対するプロセスのハンドラーがオンになります。さまざまな種類のオペレーティング システムには、セグメンテーション フォールトが発生したことを示すための個別の信号名があります。
- として知られる信号 シグセグブ (略して セグメンテーション違反 ) は、Unix 系オペレーティング システム上の問題のあるプロセスに転送されます。問題のあるプロセスは例外を受け取ります。つまり、 STATUS_ACCESS_VIOLATION Microsoft Windows の場合。
セグメンテーション違反の原因
セグメンテーション違反が発生する状況とそれがどのように現れるかは、オペレーティング システムとハードウェアに固有です。ハードウェアが異なれば、状況に応じてさまざまな障害が発生し、オペレーティング システムが異なれば、これらの障害がプロセスに送信される異なる信号に変換されます。
根本的な原因はいくつかの種類のソフトウェアのバグですが、今後の原因はメモリ アクセス違反である可能性があります。バグのデバッグや根本原因の特定は、プログラムが一貫してセグメンテーション違反を引き起こすいくつかのケースでは簡単に行うことができます。ただし、バッグの再現が難しく、実行のたびにメモリ割り当てに依存する場合もあります。
セグメンテーション違反の一般的な原因をいくつか次に示します。
文字列.値
- 存在しないメモリ アドレス (プロセスのアドレス空間の外部) にアクセスしようとしています。
- プログラムが権限を持たないメモリ(たとえば、 カーネル構造 プロセスコンテキスト内で)
- 読み取り専用メモリに書き込もうとしています(たとえば、 コードセグメント )
- これらは多くの場合、無効なメモリ アクセスにつながる多くのプログラミング エラーによって発生します。
- 正しくコンパイルできないプログラムを実行しようとしました。 (いくつかのコンパイラでは、コンパイル時エラーの存在に関係なく、実行可能ファイルが生成されます。)
- スタックオーバーフロー
- バッファオーバーフロー
- 解放されたポインタへの代入または参照解除 ( ぶら下がりポインタ 、削除/割り当て解除/解放されたメモリを示します)
- への割り当てまたは逆参照 初期化されていないポインタ ( ワイルドポインター 、ランダムなメモリアドレスを示します)
- への逆参照 ヌルポインタ 通常、プロセスのアドレス空間の一部ではないアドレスを示します。
セグメンテーション違反は、ポインターの使用、特に次のようなエラーが原因で発生することがよくあります。 C の動的メモリ割り当て Cコードで。への逆参照 ヌルポインタ 未定義の動作が発生すると、セグメンテーション違反が発生します。これは、有効なメモリ アドレスではない null ポインターが原因です。の ぶら下がりポインタ そして ワイルドポインタ メモリが存在する場合と存在しない可能性があり、書き込み可能または読み取り可能である場合と不可能であるため、一時的なバグが発生する可能性があることを示します。
Ubuntu のセグメンテーション違反を解決する
このエラーは、いつでも Ubuntu システムに発生する可能性があります。セグメンテーション違反は、システムが存在しないメモリのページにアクセスしようとした場合に発生します。 コアがダンプされました コード部分が空き場所または読み取り専用の場所で書き込みおよび読み取り操作を実行しようとするタイミングを定義します。一般的に、 セグメンテーション違反 これらは core という名前のファイルに関連付けられており、アップグレード時に発生します。
コア ダンプ状況時にいくつかのコマンドを実行すると、次のような問題が発生する可能性があります。 「ロックファイルを開けません」 エラー。これは、システムが存在しないブロックのビットを取得しようとしていることが原因です。これは、いくつかの特定のプログラムのバイナリがクラッシュするためです。
問題を解決するためにデバッグまたはバックトラックを行っている可能性がありますが、解決策は、次の手順を実行して壊れたパッケージを修正することです。
1. 別の場所にあるロック ファイルを削除します。
$ sudo rm -rvf /var/lib/apt/lists/lock /var/cache/apt/archives/lock /var/lib/dpkg/lock and restart our system
2. リポジトリキャッシュを削除します。
$ sudo apt-get clean all
3. リポジトリ キャッシュをアップグレードして更新します。
$ sudo apt-get update
$ sudo apt-get upgrade
4. ディストリビューションをアップグレードすると、パッケージが更新されます。
$ sudo apt-get dist-upgrade
5. 破損したパッケージを検索し、強制的に削除します。
$ sudo dpkg -1 | grep ^..r | apt-get purge
コマンドラインとは別に、常に機能する優れた方法は次のとおりです。
- スタートアップ モードで、 ESC 再起動後にキーを押します。
- 選ぶ ' Ubuntuの詳細オプション
- リカバリモードでUbuntuを実行すると、いくつかのオプションが表示されます。
- まず、 「壊れた荷物を修理する」
- 次に、 「通常のブートを再開」
現在、セグメンテーション違反を解決するには GUI と CLI の 2 つの方法があります。場合によっては、コマンド、つまり apt が機能しないことも考えられます。 セグメンテーション違反 , そのため、CLI メソッドは実装されません。そのような状況では、GUI メソッドが常に機能するため、心配する必要はありません。
セグメンテーション違反の処理
バス エラーまたはセグメンテーション フォールトのデフォルトのタスクは、バス エラーまたはセグメンテーション フォールトが発生したプロセスの異常終了です。デバッグに役立つコア ファイルが作成される場合や、その他のプラットフォームに依存するタスクも実装される場合があります。たとえば、多くの Linux システムでは、 セキュリティパッチ ログに記録するかもしれない SIGSEGV シグナル バッファ オーバーフローを伴う侵入の可能性を監視します。
Windows や Linux などのいくつかのシステムでは、プログラム自体がセグメンテーション違反を管理することが可能です。実行中のプログラムはイベントを管理できるだけでなく、プロセッサ レジスタの値、スタック トレースの取得、イベントが発生したときのソース コードの行、無効にアクセスされたメモリ アドレス、タスクが書き込みであるか読み取りであるかは、オペレーティング システムとアーキテクチャに応じて異なります。
ただし、セグメンテーション違反は、プログラムに修正が必要なエラーがあることを定義します。テストやデバッグの目的で意図的にそのような障害を引き起こすことも可能です。また、メモリへの直接アクセスが必要なプラットフォームを模倣することもできます。後者の場合、エラーが発生した後でもシステムはプログラムの実行を許可できる必要があります。
npm クリーンキャッシュ強制
この状況では、システムが許可すればイベントを管理し、プロセッサ プログラム カウンターを強化することができます。 'ジャンプ' 失敗した命令については実行を続行します。
セグメンテーション違反の例
読み取り専用メモリへの書き込み
セグメンテーション違反が発生します。これは、プログラムがコード セグメントの一部またはデータ セグメントの読み取り専用部分にコード エラー レベルで書き込むときに表示されます。これらはオペレーティング システムを介して読み取り専用メモリにロードされるためです。
Null ポインタの逆参照
C およびその他の C に似た言語では、null ポインターは意味を表すために使用されます。 'オブジェクトへのポインタ' エラー インジケーターとして、ヌル ポインターでの逆参照 (ヌル ポインターへの書き込みまたは読み取り) は、非常に基本的なプログラム エラーです。
標準では、null ポインタが 0 メモリ アドレスへのポインタに似ているとは述べていませんが、そうかもしれません。ほとんどすべてのオペレーティング システムは、ヌル ポインターを使用するとセグメンテーション フォールトが発生するように、ヌル ポインターのアドレスをマップします。
この動作はどの C 標準でも保証されていません。 C では、null ポインタの逆参照は、 未定義の動作 、準拠する実装では、逆参照されるポインターが null ではないと想定することが許可されます。