6
7

More than 1 year has passed since last update.

coreファイルを生成,参照する方法

Last updated at Posted at 2018-01-21

#1 はじめに 
systemdから起動されたプロセスのcoreファイル生成と、
systemdから起動されていないプロセスのcoreファイル生成方法について説明します。

#2 環境
VMware Workstation 12 Player上のゲストマシンを使っています。

[root@client ~]#cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

[root@client ~]# uname -r
3.10.0-514.el7.x86_64

#3 systemdが起動したプロセスのcoreファイル生成方法

下記手順に従っても、coreファイルが出力されない場合、SELinuxのポリシー違反の可能性があります。
そのような場合、文末の手順に従ってルールを作成することで、coreファイルが出力されるようになります。

##3.1 一時的な設定方法

実行結果
[root@client ~]# mkdir /var/lib/coredumps
[root@client ~]# ls -ld /var/lib/coredumps
drwxr-xr-x 2 root root 31  1月 21 09:16 /var/lib/coredumps

[root@client ~]# sysctl -w kernel.core_pattern="/var/lib/coredumps/core.%e.%p"
kernel.core_pattern = /var/lib/coredumps/core.%e.%p
[root@client ~]# sysctl -n kernel.core_pattern
/var/lib/coredumps/core.%e.%p

[root@client ~]# sysctl -w fs.suid_dumpable=2
fs.suid_dumpable = 2
[root@client ~]# sysctl -n fs.suid_dumpable
2

ユニット定義ファイルのServiceセクションにLimitCORE=infinity(★)を追加する。
[root@client ~]# cp /usr/lib/systemd/system/chronyd.service /etc/systemd/system
[root@client ~]# vi /etc/systemd/system/chronyd.service
[root@client ~]# cat /etc/systemd/system/chronyd.service
-中略-
[Service]
Type=forking
PIDFile=/var/run/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
ExecStartPost=/usr/libexec/chrony-helper update-daemon
LimitCORE=infinity ★
-以下、略-

ユニット定義ファイルの変更をsystemdに通知する。
[root@client ~]# systemctl daemon-reload

chronydを再起動する。
[root@client ~]# systemctl restart chronyd
[root@client ~]# ps -C chronyd
   PID TTY          TIME CMD
  1302 ?        00:00:00 chronyd

[root@client ~]# pkill -SIGSEGV chronyd
[root@client ~]# ps -C chronyd
   PID TTY          TIME CMD

coreファイルを確認する。PID=1302のcoreファイルが生成されていることがわかる。
[root@client ~]# ls -la /var/lib/coredumps/core.chronyd.1302
-rw------- 1 root chrony 9093120  1月 21 09:16 /var/lib/coredumps/core.chronyd.1302

##3.2 恒久的な方法
ここでは、OSがリブートしても、設定が有効になったままにする方法について説明します。

実行結果
coreファイルを保存するディレクトリを作成する。
[root@client ~]# mkdir /var/lib/coredumps

[root@client ~]# vi /etc/sysctl.d/core.conf
[root@client ~]# cat /etc/sysctl.d/core.conf
kernel.core_pattern = /var/lib/coredumps/core.%e.%p
fs.suid_dumpable = 2

[root@client ~]# sysctl --system

設定を確認する。
[root@client ~]# sysctl -n kernel.core_pattern
/var/lib/coredumps/core.%e.%p

設定を確認する。
[root@client ~]# sysctl -n fs.suid_dumpable
2

ユニット定義ファイルのServiceセクションにLimitCORE=infinity(★)を追加する。
[root@client ~]# cp /usr/lib/systemd/system/chronyd.service /etc/systemd/system
[root@client ~]# vi /etc/systemd/system/chronyd.service
[root@client ~]# cat /etc/systemd/system/chronyd.service
-中略-
[Service]
Type=forking
PIDFile=/var/run/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
ExecStartPost=/usr/libexec/chrony-helper update-daemon
LimitCORE=infinity ★
-以下、略-

OSを再起動する。
[root@client ~]# shutdown -r now

OS再起動後のSELinuxのモードを確認する。
[root@client ~]# getenforce
Permissive

プロセスの状態を確認する。
[root@client ~]# ps -C chronyd
   PID TTY          TIME CMD
   616 ?        00:00:00 chronyd

chronydプロセスにシグナル(SIGSEGV)を送信する。
[root@client ~]# pkill -SIGSEGV chronyd
[root@client ~]# ps -C chronyd
   PID TTY          TIME CMD

coreファイルを確認する。
[root@client ~]# ls -la /var/lib/coredumps/core.chronyd.613
-rw-------. 1 root chrony 9265152  5月 14 23:16 /var/lib/coredumps/core.chronyd.613

#4 systemdから起動しないプロセスのcoreファイル生成方法
##4.1 基本的な使い方

coreファイルのサイズを無制限に変更する。
[root@client core]# ulimit -c unlimited
[root@client core]# ulimit -c
unlimited

ここでは、core_patternをデフォルトのままで使用してみる。
デフォルトの場合、プログラムが実行されたディレクトリにcoreファイルが生成されます。
[root@client core]# cat /proc/sys/kernel/core_pattern
core

sleepプロセスを起動する。PIDは8783であることがわかる。
[root@client core]# sleep 300&
[1] 8783

sleepプロセスのulimitを確認する。coreファイルサイズが無制限(★)になっていることがわかる。
[root@client core]# cat /proc/8783/limits
Limit                     Soft Limit           Hard Limit           Units
Max core file size      ★unlimited            unlimited            bytes

sleepプロセスにシグナル(SIGSEGV)を送信する。
[root@client core]# pkill -SIGSEGV sleep

ファイルを確認する。coreファイルが生成されたことがわかる。
[root@client core]# ls
core.8783
[1]+  Segmentation fault      (コアダンプ) sleep 300

##4.2 coreファイルの格納場所や名前を変更する方法

coreファイルのサイズを無制限に変更する。
[root@client core]# ulimit -c unlimited
[root@client core]# ulimit -c
unlimited

coreファイルの格納場所を/tmp、coreファイルの名前はプロセス名(%e).プロセスID(%p)にする。
[root@client core]# echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern
[root@client core]# cat  /proc/sys/kernel/core_pattern
/tmp/core.%e.%p


sleepプロセスを起動する。PIDは8861であることがわかる。
[root@client core]# sleep 300&
[1] 8861

sleepプロセスのulimitを確認する。coreファイルサイズが無制限(★)になっていることがわかる。
[root@client core]# cat /proc/8861/limits
Limit                     Soft Limit           Hard Limit           Units
Max core file size      ★unlimited            unlimited            bytes

sleepプロセスにシグナル(SIGSEGV)を送信する。
[root@client core]# pkill -SIGSEGV sleep

ファイルを確認する。coreファイルが生成されたことがわかる。
[root@client core]# ls /tmp/core.sleep.8861
/tmp/core.sleep.8861
[1]+  Segmentation fault      (コアダンプ) sleep 300

#5 coreファイルの参照方法
ここでは、生成したcoreファイルをgdbで参照する方法について説明します。
gdbでcoreファイルを参照するには、debuginfoパッケージをインストールする必要があります。

##5.1 chronyd
ここでは、chronydのcoreファイルをgdbで参照してみます。

debuginfoパッケージのインストール
chronyパッケージの版数を確認する。
[root@client ~]# rpm -qa|grep chrony
chrony-2.1.1-4.el7.centos.x86_64

chronyパッケージと同じ版数のdebuginfoパッケージをインストールする。
[root@client ~]# yum --disablerepo=* --enablerepo=base-debuginfo install chrony-debuginfo-2.1.1-4.el7.centos.x86_64

chronyのdebuginfoパッケージ(★)がインストールされたことがわかる。
[root@client ~]# rpm -qa|grep chrony
chrony-2.1.1-4.el7.centos.x86_64
chrony-debuginfo-2.1.1-4.el7.centos.x86_64 ★
gdbによるcoreファイル参照
[root@client ~]# gdb /var/lib/coredumps/core.chronyd.1302
-中略-
(gdb) set pagination off
(gdb) bt full
#0  0x00007fc672386ba3 in select () from /lib64/libc.so.6
No symbol table info available.
#1  0x00007fc6731aedf9 in SCH_MainLoop () at sched.c:650
        rd = {fds_bits = {6, 0 <repeats 15 times>}}
        status = <optimized out>
        errsv = <optimized out>
        tv = {tv_sec = 0, tv_usec = 127043}
        saved_tv = {tv_sec = 0, tv_usec = 167708}
        ptv = 0x7ffdc1a5ff40
        now = {tv_sec = 1516493770, tv_usec = 715689}
        saved_now = {tv_sec = 1516493770, tv_usec = 715689}
        cooked = {tv_sec = 1516493770, tv_usec = 714225}
        err = 0
        __PRETTY_FUNCTION__ = "SCH_MainLoop"
        __FUNCTION__ = "SCH_MainLoop"
#2  0x00007fc6731a48a4 in main (argc=0, argv=0x7ffdc1a60200) at main.c:534
        conf_file = <optimized out>
        progname = 0x7ffdc1a60f8c "/usr/sbin/chronyd"
        user = 0x7fc674728460 "chrony"
        debug = 0
        nofork = 0
        address_family = 0
        do_init_rtc = 0
        restarted = 0
        other_pid = <optimized out>
        lock_memory = 0
        sched_priority = 0
        system_log = 1
        config_args = <optimized out>
        __FUNCTION__ = "main"

##5.2 httpd
ここでは、httpdのcoreファイルをgdbで参照してみます。

debuginfoパッケージのインストール(httpd)
httpdパッケージの版数を確認する。
[root@client ~]# rpm -qa|grep httpd
httpd-2.4.6-67.el7.centos.6.x86_64
httpd-tools-2.4.6-67.el7.centos.6.x86_64

[root@client ~]# yum --disablerepo=* --enablerepo=base-debuginfo install httpd-debuginfo-2.4.6-67.el7.centos.6.x86_64

httpdのdebuginfoパッケージ(★)がインストールされたことがわかる。
[root@client ~]# rpm -qa|grep httpd
httpd-2.4.6-67.el7.centos.6.x86_64
httpd-tools-2.4.6-67.el7.centos.6.x86_64
httpd-debuginfo-2.4.6-67.el7.centos.6.x86_64 ★
debuginfoパッケージのインストール(glibc)
glibcパッケージの版数を確認する。
[root@client ~]# rpm -qa|grep glibc
glibc-common-2.17-157.el7.x86_64
glibc-2.17-157.el7.x86_64
glibc-devel-2.17-157.el7.x86_64
glibc-headers-2.17-157.el7.x86_64

[root@client ~]# yum --disablerepo=* --enablerepo=base-debuginfo install glibc-debuginfo-2.17-157.el7.x86_64

glibcのdebuginfoパッケージ(★)がインストールされたことがわかる。
[root@client ~]# rpm -qa|grep glibc
glibc-common-2.17-157.el7.x86_64
glibc-debuginfo-common-2.17-157.el7.x86_64
glibc-2.17-157.el7.x86_64
glibc-devel-2.17-157.el7.x86_64
glibc-debuginfo-2.17-157.el7.x86_64 ★
glibc-headers-2.17-157.el7.x86_64
gdbによるcoreファイル参照
[root@client ~]# ls -l /var/lib/coredumps/core.httpd.*
-rw------- 1 root root   2678784  1月 21 09:38 /var/lib/coredumps/core.httpd.1393
-rw------- 1 root apache 2678784  1月 21 09:38 /var/lib/coredumps/core.httpd.1394
-rw------- 1 root apache 2678784  1月 21 09:38 /var/lib/coredumps/core.httpd.1395
-rw------- 1 root apache 2678784  1月 21 09:38 /var/lib/coredumps/core.httpd.1396
-rw------- 1 root apache 2678784  1月 21 09:38 /var/lib/coredumps/core.httpd.1397
-rw------- 1 root apache 2678784  1月 21 09:38 /var/lib/coredumps/core.httpd.1398

[root@client ~]# gdb /var/lib/coredumps/core.httpd.1393
-中略-
(gdb) set pagination off
(gdb) bt full
#0  0x00007f85c9e88b83 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:81
No locals.
#1  0x00007f85ca59f585 in apr_sleep () from /lib64/libapr-1.so.0
No symbol table info available.
#2  0x00007f85cb8c2971 in ap_wait_or_timeout (status=status@entry=0x7ffef45e7608, exitcode=exitcode@entry=0x7ffef45e760c, ret=ret@entry=0x7ffef45e7610, p=<optimized out>, s=<optimized out>) at mpm_common.c:195
        rv = <optimized out>
#3  0x00007f85c14dc13e in prefork_run (_pconf=<optimized out>, plog=<optimized out>, s=<optimized out>) at prefork.c:1016
        status = 32645
        pid = {pid = -1, in = 0x7f8500000000, out = 0x7f85cc390450, err = 0x3}
        child_slot = <optimized out>
        exitwhy = (APR_PROC_SIGNAL_CORE | unknown: 3228138712)
        processed_status = <optimized out>
        index = <optimized out>
        remaining_children_to_start = 0
        rv = <optimized out>
#4  0x00007f85cb8c215e in ap_run_mpm (pconf=pconf@entry=0x7f85cc2f8138, plog=0x7f85cc325358, s=0x7f85cc31f310) at mpm_common.c:96
        pHook = <optimized out>
        n = 0
        rv = -1
#5  0x00007f85cb8baed6 in main (argc=2, argv=0x7ffef45e7908) at main.c:783
        c = 68 'D'
        showcompile = 0
        showdirectives = 0
        confname = 0x7f85cb8f95cf "conf/httpd.conf"
        def_server_root = 0x7f85cb8f95c4 "/etc/httpd"
        temp_error_log = 0x0
        error = <optimized out>
        process = 0x7f85cc2f6218
        pconf = 0x7f85cc2f8138
        plog = 0x7f85cc325358
        ptemp = 0x7f85cc323348
        pcommands = 0x7f85cc31a248
        opt = 0x7f85cc31a338
        rv = <optimized out>
        mod = 0x7f85cbb18098 <ap_prelinked_modules+24>
        opt_arg = 0x7ffef45e7f7d "FOREGROUND"
        signal_server = <optimized out>

#Y SELinuxのルール作成方法

##Y.1 ポリシー違反時のエラーメッセージ
coreファイルが出力されない原因の1つに、SELinuxのポリシーに違反している可能性があります。
そのような場合、/var/log/audit/audit.logに下記エラーメッセージが出力されます。

type=ANOM_ABEND msg=audit(1526305553.727:554): auid=4294967295 uid=998 gid=996 ses=4294967295 subj=system_u:system_r:chronyd_t:s0 pid=24252 comm="chronyd" reason="memory violation" sig=11
type=AVC msg=audit(1526305553.728:555): avc:  denied  { create } for  pid=24252 comm="chronyd" name="core.chronyd.24252" scontext=system_u:system_r:chronyd_t:s0 tcontext=system_u:object_r:var_lib_t:s0 tclass=file
type=SERVICE_STOP msg=audit(1526305553.736:556): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=chronyd comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=failed'

##Y.2 ルールの作成方法

ppファイルの作成
[root@centos74 ~]# audit2allow -M test < /var/log/audit/audit.log
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i test.pp
audit2allowにより生成したファイル
[root@centos74 ~]# ls test.*
test.pp  test.te
test.ppの中身の確認
[root@centos74 ~]# cat test.te

module test 1.0;

require {
        type chronyd_t;
        type tmp_t;
        type var_lib_t;
        class file { create open read write };
        class dir write;
}

#============= chronyd_t ==============

#!!!! WARNING: 'tmp_t' is a base type.
allow chronyd_t tmp_t:dir write;

#!!!! WARNING 'chronyd_t' is not allowed to write or create to var_lib_t.  Change the label to chronyd_var_lib_t.
allow chronyd_t var_lib_t:file { create open read write };
モジュールのインストール
[root@centos74 ~]# semodule -i test.pp
[root@centos74 ~]# semodule -l|grep -w test
test    1.0

#Z 参考
Enable Core Dump systemd
CentOS7の/etc/sysctl.d/以下の設定ファイルの反映方法
Enable core dumps for systemd services on CentOS 7

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7