Segment fault (segfault)

RHEL 6 (kenel-2.6.32) において、以下のような segfault が発生した。

```
segfault at ff ip xxxxxxxxxxxxxxxx sp xxxxxxxxxxxxxxxx error 6 in mssql.so[xxxxxxxxxxxx+b000]
```

## fault.c
```c:arch/x86/mm/fault.c#L31
/*
 * 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,
};
```
```c:arch/x86/mm/fault.c#L830
/*
 * 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](https://github.com/torvalds/linux/blob/master/arch/x86/mm/fault.c) には上記のような記載がある。

## Page-fault exceptions

![page_fault.png](https://qiita-image-store.s3.amazonaws.com/0/15175/e723ef3e-e8a6-c9cf-196d-76e34c4e9c5e.png)
["Intel® 64 and IA-32 Architectures Software Developer’s Manual" Volume 3A: System Programming Guide, Part 1](http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf#page=136) には上記のような記載がある。

## \<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-](https://web.archive.org/web/20130524122248/https://ossmpedia.org/messages/linux/2.6.9-34.EL/56980.ja) には上記のような記載がある。[^ossmpedia]

[^ossmpedia]: OSSメッセージペディアは2017/04/30にサイトを閉鎖するらしいので全文引用

## 10進数→2進数変換
```bash
printf "%06d\n" `echo "ibase=10;obase=2; 6" | bc`
```
```
000110
```

## 参考文献
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その1) - Qiita](http://qiita.com/akachochin/items/e5fcefbd27f6c9fd711c)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その2) - Qiita](http://qiita.com/akachochin/items/5121d658fa62fb116728)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その3) - Qiita](http://qiita.com/akachochin/items/396f88c65fd81be1333a)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その4) - Qiita](http://qiita.com/akachochin/items/6e38f89f9421f3e7cbcf)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その5) - Qiita](http://qiita.com/akachochin/items/e7ffdca00c00d322022a)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その6) - Qiita](http://qiita.com/akachochin/items/7ab3ea00b346bd4a3de1)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その7) - Qiita](http://qiita.com/akachochin/items/325863a6699000e228b8)
* [Linux(x86-32bit)のページフォルトハンドラを読んでみる(その8) - Qiita](http://qiita.com/akachochin/items/a2ad7770b30c8841c064)