セグメンテーション違反

セグメンテーション違反英語: segmentation fault)とは、ソフトウェア実行時のフォールト状態(あるいはフォールト条件)の一種であり、ソフトウェアがアクセス禁止とされているメモリ上のエリアにアクセスしようとしたり、メモリ上の位置ごとに設定されているルールに違反してメモリにアクセスしようとするときに起こるものである。略してセグフォールト: segfault)とも。

Kritaのセグメンテーション違反の例

たとえば、あるソフトウェアがオペレーティングシステム(OS)を上書きしようとしたり、そのソフトウェアに関してはリードオンリーと設定されている位置へ当該ソフトが書き込みをしようとする時に起こる。

UNIX系のオペレーティングシステム上では、不正なメモリにアクセスをするプロセスはSIGSEGVシグナルを受け取る。Microsoft Windows上では、不正なメモリにアクセスするプロセスはSTATUS_ACCESS_VIOLATION例外を受け取る。

なおx86プロセッサによるシステムでは、この種のイベントはen:general protection fault扱いになり、 MC68000のようなプロセッサによるシステムはこれらのイベントを「アドレスエラー」もしくは「バスエラー」として参照しようとする傾向にある。

セグメント方式は、メモリ管理およびOS保護の手法の一種である。大部分の用途のためにページング方式に置き換えられつつあるが、セグメンテーションの専門用語はまだ多く使用されている。セグメンテーション違反はその一例である。オペレーティングシステムの中にはメインメモリ管理の方針としてページング方法が使用されているが、いくつかの論理レベルでまだセグメンテーションを持つものがある。

次のANSI C言語のコードはメモリ保護機能を持つプラットフォーム上でセグメンテーション違反を作り出す例である。

const char *s = "hello world";
*s = 'H';

このコードを含むプログラムがコンパイルされた時、"hello world"の文字列リテラルはリードオンリーとしてマークされたプログラムバイナリのセクションに置かれる; ロードされたとき、オペレーティングシステムはそれをリードオンリーのメモリーセグメントで他の文字列と定数データで置き換える。 実行されたとき、s変数は、文字列の位置を指定するように設定され、変数を通してH文字をメモリに書き込むことが企てられるが、結果はセグメンテーション違反が起こる。このようなプログラムをコンパイルして実行すると、例えば次のようなランタイムエラーを起こす:

$ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault

以下はGNUデバッガからのスタックトレースである:

Program received signal SIGSEGV, Segmentation fault.
0x1c0005c2 in main () at segfault.c:6
6               *s = 'H';

一方で、Linux上のgcc 4.1.1はデフォルトでコンパイル時エラーを発生させる:

$ gcc segfault.c -g -o segfault
segfault.c: In function ‘main’:
segfault.c:4: error: assignment of read-only location

セグメンテーション違反が起こる条件とそれらをそれら自身で宣言する方法はオペレーティングシステム特有のものである。

非常に一般的なプログラムエラーはNullポインタ参照外し(Nullポインタを通した読み込みもしくは書き込み、C言語では"存在しないオブジェクトへのポインタ"を意味し、エラーインディケータとして使用される)であるので、大抵のオペレーティングシステムはアクセスがセグメンテーション違反を引き起こすようなアドレスをNullポインタにマッピングする。

関連項目

編集

外部リンク

編集