コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

「セグメンテーション違反」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
Cewbot (会話 | 投稿記録)
m Bot作業依頼: sourceタグをsyntaxhighlightタグに置換 (Category:非推奨のsourceタグを使用しているページ) - log
8行目: 8行目:
== 例 ==
== 例 ==
次の[[ANSI]] [[C言語]]のコードは[[メモリ保護機能]]を持つプラットフォーム上でセグメンテーション違反を作り出す例である。
次の[[ANSI]] [[C言語]]のコードは[[メモリ保護機能]]を持つプラットフォーム上でセグメンテーション違反を作り出す例である。
<source lang="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''文字をメモリに書き込むことが企てられるが、結果はセグメンテーション違反が起こる。このようなプログラムをコンパイルして実行すると、例えば次のような[[ランタイムライブラリ|ランタイム]]エラーを起こす:
<source lang="text">
<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デバッガ]]からの[[スタックトレース]]である:
<source lang="text">
<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はデフォルトでコンパイル時エラーを発生させる:
<source lang="text">
<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

以下は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ポインタにマッピングする。

関連項目

外部リンク