「セグメンテーション違反」の版間の差分
m →例 |
|||
8行目: | 8行目: | ||
== 例 == |
== 例 == |
||
次の[[ANSI]] [[C言語]]のコードは[[メモリ保護機能]]を持つプラットフォーム上でセグメンテーション違反を作り出す例である。 |
次の[[ANSI]] [[C言語]]のコードは[[メモリ保護機能]]を持つプラットフォーム上でセグメンテーション違反を作り出す例である。 |
||
< |
<syntaxhighlight lang="c"> |
||
const char *s = "hello world"; |
const char *s = "hello world"; |
||
*s = 'H'; |
*s = 'H'; |
||
</syntaxhighlight> |
|||
</source> |
|||
このコードを含むプログラムが[[コンパイラ|コンパイル]]された時、"hello world"の[[文字列]]リテラルはリードオンリーとしてマークされたプログラム[[実行ファイル|バイナリ]]のセクションに置かれる; ロードされたとき、オペレーティングシステムはそれをリードオンリーのメモリーセグメントで他の文字列と[[定数]]データで置き換える。 |
このコードを含むプログラムが[[コンパイラ|コンパイル]]された時、"hello world"の[[文字列]]リテラルはリードオンリーとしてマークされたプログラム[[実行ファイル|バイナリ]]のセクションに置かれる; ロードされたとき、オペレーティングシステムはそれをリードオンリーのメモリーセグメントで他の文字列と[[定数]]データで置き換える。 |
||
実行されたとき、''s''変数は、文字列の位置を指定するように設定され、変数を通して''H''文字をメモリに書き込むことが企てられるが、結果はセグメンテーション違反が起こる。このようなプログラムをコンパイルして実行すると、例えば次のような[[ランタイムライブラリ|ランタイム]]エラーを起こす: |
実行されたとき、''s''変数は、文字列の位置を指定するように設定され、変数を通して''H''文字をメモリに書き込むことが企てられるが、結果はセグメンテーション違反が起こる。このようなプログラムをコンパイルして実行すると、例えば次のような[[ランタイムライブラリ|ランタイム]]エラーを起こす: |
||
< |
<syntaxhighlight lang="text"> |
||
$ gcc segfault.c -g -o segfault |
$ gcc segfault.c -g -o segfault |
||
$ ./segfault |
$ ./segfault |
||
Segmentation fault |
Segmentation fault |
||
</syntaxhighlight> |
|||
</source> |
|||
以下は[[GNUデバッガ]]からの[[スタックトレース]]である: |
以下は[[GNUデバッガ]]からの[[スタックトレース]]である: |
||
< |
<syntaxhighlight lang="text"> |
||
Program received signal SIGSEGV, Segmentation fault. |
Program received signal SIGSEGV, Segmentation fault. |
||
0x1c0005c2 in main () at segfault.c:6 |
0x1c0005c2 in main () at segfault.c:6 |
||
6 *s = 'H'; |
6 *s = 'H'; |
||
</syntaxhighlight> |
|||
</source> |
|||
一方で、[[Linux]]上のgcc 4.1.1はデフォルトでコンパイル時エラーを発生させる: |
一方で、[[Linux]]上のgcc 4.1.1はデフォルトでコンパイル時エラーを発生させる: |
||
< |
<syntaxhighlight lang="text"> |
||
$ gcc segfault.c -g -o segfault |
$ gcc segfault.c -g -o segfault |
||
segfault.c: In function ‘main’: |
segfault.c: In function ‘main’: |
||
segfault.c:4: error: assignment of read-only location |
segfault.c:4: error: assignment of read-only location |
||
</syntaxhighlight> |
|||
</source> |
|||
セグメンテーション違反が起こる条件とそれらをそれら自身で宣言する方法はオペレーティングシステム特有のものである。 |
セグメンテーション違反が起こる条件とそれらをそれら自身で宣言する方法はオペレーティングシステム特有のものである。 |
2020年7月5日 (日) 22:56時点における版
セグメンテーション違反(英語: segmentation fault)はソフトウェアの実行時に起きる特定のエラー条件である。segfault(セグフォールト)と略される場合がある。 セグメンテーション違反はアクセスが許可されていないメモリ上の位置、もしくは許可されていない方法(例えばリードオンリーの位置へ書き込みをしようとする、もしくはオペレーティングシステムの部分を上書きしようとする)でメモリ上の位置にアクセスしようとするときに起こる。MC68000のようなプロセッサに基づくシステムはこれらのイベントをアドレスエラーもしくはバスエラーとして参照しようとする傾向にある。
セグメント方式はメモリ管理とオペレーティングシステムを保護する方法の一つである。大部分の用途のためにページング方式に置き換えられつつあるが、セグメンテーションの専門用語はまだ多く使用されている。セグメンテーション違反はその一例である。オペレーティングシステムの中にはメインメモリ管理の方針としてページング方法が使用されているがいくつかの論理レベルでまだセグメンテーションを持つものがある。
UNIXライクのオペレーティングシステム上では、不正なメモリにアクセスをするプロセスはSIGSEGVシグナルを受け取る。Microsoft Windows上では、不正なメモリにアクセスするプロセスはSTATUS_ACCESS_VIOLATION例外を受け取る。
例
次のANSI C言語のコードはメモリ保護機能を持つプラットフォーム上でセグメンテーション違反を作り出す例である。
const char *s = "hello world";
*s = 'H';
このコードを含むプログラムがコンパイルされた時、"hello world"の文字列リテラルはリードオンリーとしてマークされたプログラムバイナリのセクションに置かれる; ロードされたとき、オペレーティングシステムはそれをリードオンリーのメモリーセグメントで他の文字列と定数データで置き換える。 実行されたとき、s変数は、文字列の位置を指定するように設定され、変数を通してH文字をメモリに書き込むことが企てられるが、結果はセグメンテーション違反が起こる。このようなプログラムをコンパイルして実行すると、例えば次のようなランタイムエラーを起こす:
$ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault
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ポインタにマッピングする。
関連項目
- バッファオーバーラン
- バスエラー
- コアダンプ
- Segfault - このエラーの名前を取ったユーモアウェブサイト。
外部リンク
- A FAQ: User contributed answers regarding the definition of a segmentation fault
- A "null pointer" explained
- Answer to: NULL is guaranteed to be 0, but the null pointer is not?
- Resolving crashes and segmentation faults, an article from the Real-Time embedded blog.
- The Open Group Base Specifications Issue 6 signal.h