RHEL 6 (kenel-2.6.32) において、以下のような segfault が発生した。
segfault at ff ip xxxxxxxxxxxxxxxx sp xxxxxxxxxxxxxxxx error 6 in mssql.so[xxxxxxxxxxxx+b000]
fault.c
/*
* Page fault error code bits:
*
* bit 0 == 0: no page found 1: protection fault
* bit 1 == 0: read access 1: write access
* bit 2 == 0: kernel-mode access 1: user-mode access
* bit 3 == 1: use of reserved bit detected
* bit 4 == 1: fault was an instruction fetch
* bit 5 == 1: protection keys block access
*/
enum x86_pf_error_code {
PF_PROT = 1 << 0,
PF_WRITE = 1 << 1,
PF_USER = 1 << 2,
PF_RSVD = 1 << 3,
PF_INSTR = 1 << 4,
PF_PK = 1 << 5,
};
/*
* Print out info about fatal segfaults, if the show_unhandled_signals
* sysctl is set:
*/
static inline void
show_signal_msg(struct pt_regs *regs, unsigned long error_code,
unsigned long address, struct task_struct *tsk)
{
if (!unhandled_signal(tsk, SIGSEGV))
return;
if (!printk_ratelimit())
return;
printk("%s%s[%d]: segfault at %lx ip %p sp %p error %lx",
task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, task_pid_nr(tsk), address,
(void *)regs->ip, (void *)regs->sp, error_code);
print_vma_addr(KERN_CONT " in ", regs->ip);
printk(KERN_CONT "\n");
}
arch/x86/mm/fault.c には上記のような記載がある。
Page-fault exceptions
"Intel® 64 and IA-32 Architectures Software Developer’s Manual" Volume 3A: System Programming Guide, Part 1 には上記のような記載がある。
<command[pid]>: segfault at address...
メッセージ
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'。説明
ユーザ空間でページフォルトが発生した場合に、該当プログラムが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'に変更することで、出力を抑止できるようだ。
OSS Message Pedia -mid:56980- には上記のような記載がある。1
10進数→2進数変換
printf "%06d\n" `echo "ibase=10;obase=2; 6" | bc`
000110
参考文献
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その1) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その2) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その3) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その4) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その5) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その6) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その7) - Qiita
- Linux(x86-32bit)のページフォルトハンドラを読んでみる(その8) - Qiita
-
OSSメッセージペディアは2017/04/30にサイトを閉鎖するらしいので全文引用 ↩