[Linux] coreファイルについて

coreファイルとはプロセスが異常終了した時のメモリ内容をダンプしたもの。
各変数の値やスレッドの状態、終了した時のソースコードの行数などを確認することができる

# coreファイルを出力するには

ulimitコマンドでcoreファイルの出力サイズを設定する
以下の場合、無制限の大きさのcoreファイルを出力することができる

```shell-session
# ulimit -c unlimited
```

0に設定するとcoreファイルは生成されない

ulimitコマンドではシェルに適用される。ログインシェルで常に適用させたい場合は /etc/security/limits.conf に設定を入れればよい
但し、PAM認証が使われている環境であること

/etc/security/limits.conf に以下の行を追加してください

```ini
*               soft    core     unlimited
```

## システム起動時に起動するプロセスで、常にcoreファイルを出力するようにしたい場合

### 1. initを使う環境の場合
initスクリプト(/etc/init.d/XXXX)で /etc/rc.d/init.d/functions を読み込む前に以下の行を追加する

```ini
DAEMON_COREFILE_LIMIT=unlimited
```

※ /etc/rc.d/init.d/functions の中で DAEMON_COREFILE_LIMIT の値でulimitを実行するようになっている。functionsのスクリプトが無い環境の場合は、initスクリプトの中でulimitコマンドを実行するようにしてください

### 2. systemdを使う環境の場合

UnitのServiceセクションにLimitCOREの設定を追加する

```shell-session
# systemctl edit %%Unit名%%.service
```

エディタが起動して、/etc/systemd/system/%%Unit名%%.service.d/override.conf が開かれる。以下の行を記述して保存

```ini
[Service]
LimitCORE=infinity
```

参考
man systemd.exec

変更後

```shell-session
# systemctl restart %%Unit名%%.service
```
を実行してサービスを再起動してください

# coreファイルを出力する設定になっているか確認

```shell-session
# cat /proc/%%プロセスID%%/limits
```

出力内容のMax core file sizeを確認する。0になっていればcoreファイルは出力されない

# 稼働中のプロセスにcoreを吐かせる

プログラムが実行中にデッドロックしてしまうなど、起動中の状態を確認したい時は、gcoreコマンドを使う

```shell-session
# gcore %%プロセスID%%
```

実行例

```shell-session
# gcore 26048
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007fb8944de470 in __nanosleep_nocancel () from /lib64/libc.so.6
Saved corefile core.26048
```

gcoreの実行場所にcoreファイルが保存される


# Coreファイルの出力先

初期状態では以下のようになっており、プログラムの作業ディレクトリに生成される

```shell-session
# cat /proc/sys/kernel/core_pattern
core
```

※補足：プログラムの作業ディレクトリの確認
/procディレクトリにある、cwdのリンク先で確認できる。以下の場合はルート(/)となっている

```shell-session
# ls -l /proc/%%プロセスID%%/cwd
lrwxrwxrwx 1 root root 0  3月 27 21:33 2015 /proc/%%プロセスID%%/cwd -> /
```

カーネルによってはcwdのリンクが作成されない場合がある。その時はlsofコマンドで確認できる

```shell-session
# lsof -p %%プロセスID%%| grep cwd
```

coreの出力先はカーネルパラメータの設定で変更できる

```shell-session
# echo "/tmp/core" > /proc/sys/kernel/core_pattern
```

ファイル名にパターンを入れることで任意の値を付けることもできる

パターン|内容
---+----
%%|1 つの % 文字
%c|クラッシュしたプロセスのコアファイルのサイズに関するソフトリソース上限 (Linux 2.6.24 以降)
%d|ダンプモード --- prctl(2) PR_GET_DUMPABLE が返す値と同じ (Linux 3.7 以降)
%e|実行ファイル名 (パス名のプレフィックスは含まれない)
%E|実行ファイルのパス名。スラッシュ ('/') は感嘆符 ('!') に置き換えられる。 (Linux 3.0 以降)
%g|ダンプされたプロセスの実グループ ID (real GID)
%h|ホスト名 (uname(2) で返される nodename と同じ)
%p|ダンプされるプロセスの PID; そのプロセスが属している PID 名前空間での PID
%P|ダンプされるプロセスの PID; 元の PID 名前空間での値 (Linux 3.12 以降)
%s|ダンプを引き起こしたシグナルの番号
%t|ダンプ時刻、紀元 (Epoch; 1970-01-01 00:00:00 +0000 (UTC)) からの秒数。
%u|ダンプされたプロセスの実ユーザー ID (real UID)

オンラインマニュアル(Man page of CORE)より抜粋

# Coreファイル作成元の確認

coreファイルをfileコマンドにかければ、作成元を確認することができる

例: httpdによって出力されたcoreファイルの場合

```shell-session
# file core.34645
core.34645: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/usr/sbin/httpd'
```

# 参考
Man page of CORE
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man5/core.5.html

7-6. coreファイルから情報が漏れる
https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b07_06.html

Red Hat Enterprise Linux 用 Agent での core ファイルの生成方法 | サポート Q&amp;A：トレンドマイクロ
http://esupport.trendmicro.com/solution/ja-jp/1310022.aspx