メッセージ
command[pid]: segfault at address rip fault_address rsp stack_address error error_code変数
command[pid] ページフォルトが発生したプロセスのコマンド名とプロセスID。 address ページフォルトを発生させた仮想アドレス(リニアアドレス) fault_address ページフォルトを発生させた命令アドレス stack_address ページフォルトを発生した際のスタックポインタ error_code 以下のフラグの組み合わせで表すエラーコード bit0:: フォルトの原因を示すフラグ("0"=ページが見つからなかった "1"=ページプロテクション(保護例外)を検出した) bit1:: 該当メモリへのアクセス種別を示すフラグ("0"=読み込み "1"=書き込み) bit2:: フォルトが発生したモードを示すフラグ("0"=カーネルモード "1"=ユーザモード) bit3:: カーネルのページテーブルに不正を検出した際に設定されるフラグ。正確には将来予約されるビットフィールド(予約ビット)に"1"が設定されたことを検知した場合に"1"となる。通常は"0"。http://ossmpedia.org/messages/linux/2.6.9-34.EL/56980.ja説明
ユーザ空間でページフォルトが発生した場合に、該当プログラムがSIGSEGVに対応するシグナル出口を登録していない場合(SIG_IGN、またはSIG_DFLを設定している)に発生したフォルト情報をトレースするためのデバッグメッセージである。
本メッセージを出力後にSIG_IGN、またはSIG_DFLのシグナル処理を続ける。
x86_64カーネル(kernel-2.6.9-34.EL)は当該デバッグメッセージが標準で出力される設定となっている。この設定を無効にしたい場合は、/proc/sys/debug/exception_trace、またはsysctlコマンドで該当kernelパラメタを"0"に変更することで、出力を抑止できるようだ。
例えば、こんなエラーが出た場合、
ora_pmon_orcl[6500]: segfault at ... rip ... rsp ... error 4
10進数の4は
% perl -le 'print unpack(q/B8/,pack(q/C/,4))' 00000100
2進数だと 100 だから、ユーザーモードでメモリから読み込もうとしたがページが見つからなかったということになる。
エキスパートCプログラミング―知られざるCの深層 (Ascii books)
P.197 Software Dogma メモリ領域が足りない?
に興味深いことが書かれていた。
OS が提供できる以上のメモリを要求すると、プログラムは「セグメントフォールト」で終了させられる。
ここで紹介する方法を使えば、セグメントフォールトの原因がそれなのか、他のバグなのかを区別できる。
スタック領域を使い尽くしたかどうかを判断するには、dbx を使う。
(中略)
Cシェルなら、セグメントの限界を変更できる。limit stacksize 10
(中略)
上のコマンドだと、スタックの最大サイズを10Kバイトに設定している。