crashの拡張モジュールインストール方法

#1 拡張モジュールとは?
拡張モジュールを使うと、crashコマンドに機能を追加することができます。
以下はRedHatより提供されている拡張モジュールです。
https://people.redhat.com/anderson/extensions.html
また、拡張モジュールは自作することもできます。

ここでは、拡張モジュールのインストール方法について説明します。
なお、crashは、[ここ(crashコマンドの使い方)](https://qiita.com/hana_shin/items/02d8da181c8287580613)を参照してください。

#2 環境
VMware Workstation 14 Playerでゲストマシンを作成しました。
仮想マシンのOS版数は以下のとおりです。

```
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[root@server ~]# uname -r
3.10.0-693.el7.x86_64
```

#3 事前準備
##3.1 rpmパッケージのインストール

crashとcrash-develパッケージをインストールします。

```console:rpmパッケージのインストール
[root@server ~]# yum -y install crash crash-devel
[root@server ~]# crash --version

crash 7.2.3-8.el7
(以下、略)
```

##3.2 src.rpmパッケージのインストール
crashのソースパッケージをインストールします。
拡張モジュールは、crashのソースを展開したディレクトリでコンパイルします。

```console:ソースパッケージのダウンロード
[root@server ~]# yumdownloader --source crash
[root@server ~]# ls crash-7.2.3-8.el7.src.rpm
crash-7.2.3-8.el7.src.rpm
```

```console:ソースパッケージのインストール
[root@server ~]# rpm -ivh crash-7.2.3-8.el7.src.rpm
```

##3.3 ソースの展開
rpmbuildコマンドを実行して、crashのソースコードを展開します。

```console:ソースの展開
[root@server SPECS]# pwd
/root/rpmbuild/SPECS

[root@server SPECS]# ls crash.spec
crash.spec
[root@server SPECS]# rpmbuild -bp crash.spec
```


#4 echoモジュール
echoモジュールは、ダンプファイルを解析するうえで、
有益な情報をえるためのものではありません。
拡張モジュールを自作する場合のソースコード(見本)を提供します。


##4.1 echoモジュールの作成
RedHatのサイトから、
/root/rpmbuild/BUILD/crash-7.2.3/extensionsにソースファイルをダウンロードします。

```console:ソースファイルのダウンロード
[root@server extensions]# pwd
/root/rpmbuild/BUILD/crash-7.2.3/extensions

[root@server extensions]# wget https://people.redhat.com/anderson/crash_sources/extensions/echo.c
[root@server extensions]# ls echo.c
echo.c
```
ソースのコンパイルは、/root/rpmbuild/BUILD/crash-7.2.3で実行します。

```console:コンパイル
[root@server crash-7.2.3]# pwd
/root/rpmbuild/BUILD/crash-7.2.3

[root@server crash-7.2.3]# make extensions
gcc -Wall -g -shared -rdynamic -o echo.so echo.c -fPIC -DX86_64  -DGDB_7_6
eppic.so: build failed: requires the crash gdb-7.6 module
gcc -Wall -g -shared -rdynamic -o trace.so trace.c -fPIC -DX86_64  -DGDB_7_6
gcc -Wall -g -shared -rdynamic -o dminfo.so dminfo.c -fPIC -DX86_64  -DGDB_7_6
gcc -Wall -g -I. -shared -rdynamic -o snap.so snap.c -fPIC -DX86_64  -DGDB_7_6
```

echo.soというモジュールが作成されたことがわかります。

```console:モジュールの確認
[root@server crash-7.2.3]# ls extensions/echo.so
extensions/echo.so
```

##4.2 モジュールのロード

```console:crashコマンドの実行
[root@server ~]# crash
```

extendコマンドを実行して、echoモジュールをロードします。

```console:モジュールのロード
crash> extend /root/rpmbuild/BUILD/crash-7.2.3/extensions/echo.so
/root/rpmbuild/BUILD/crash-7.2.3/extensions/echo.so: shared object loaded
```

モジュールをロードすると、ヘルプを確認することができるようになります。

```console:ヘルプの確認
crash> help echo

NAME
  echo - echoes back its arguments

SYNOPSIS
  echo arg ...
```

##4.3 モジュールの実行
ロードしたechoモジュールを実行してみます。
echoモジュールは、引数に指定したパラメータをエコーバックするだけです。

```
crash> echo This is test
This is test
```

##4.4 モジュールのアンロード(-u)

```モジュールのアンロード
crash> extend -u /root/rpmbuild/BUILD/crash-7.2.3/extensions/echo.so
/root/rpmbuild/BUILD/crash-7.2.3/extensions/echo.so: shared object unloaded
```



#5 gcoreモジュール
gcoreモジュール（以降gcore)は、カーネルのダンプファイルから、
ユーザモードプロセスのコアファイルを生成するときに使います。
なお、gcoreは、ライブダンプには使えません。カーネルダンプファイルに対して使います。

##5.1 パッケージのインストール
gcoreは、rpmパッケージとし提供されているので、ここでは、それを使います。
echoのように、ソースをコンパイルしてもかまいません。

```console:gcoreのインストール
[root@server ~]# yum install crash-gcore-command.x86_64
```

```console:パッケージの確認
[root@server ~]# rpm -qa|grep crash
crash-gcore-command-1.3.1-0.el7.x86_64
crash-7.2.3-8.el7.x86_64
crash-devel-7.2.3-8.el7.x86_64
```

crash-gcore-commandをインストールすると、
/usr/lib64/crash/extensions配下にgcore.soがインストールされます。

```console:gcore.soのインストール先ディレクトリの確認
[root@server ~]# rpm -ql crash-gcore-command-1.3.1-0.el7.x86_64
/usr/lib64/crash/extensions/gcore.so
/usr/share/doc/crash-gcore-command-1.3.1
/usr/share/doc/crash-gcore-command-1.3.1/COPYING
```

##5.2 モジュールのロード

```cosole:crashコマンドの実行
[root@server ~]# crash
```

extendコマンドを実行して、gcoreモジュールをロードします。

```console:モジュールのロード
crash> extend /usr/lib64/crash/extensions/gcore.so
/usr/lib64/crash/extensions/gcore.so: shared object loaded
```

モジュールをロードすると、ヘルプを確認することができるようになります。

```console:ヘルプの確認
crash> help gcore

NAME
  gcore - gcore - retrieve a process image as a core dump

SYNOPSIS
  gcore
  gcore [-v vlevel] [-f filter] [pid | taskp]*
  This command retrieves a process image as a core dump.
(以下、略)
```

##5.3 モジュールのアンロード(-u)
gcoreをアンロードします。

```console:モジュールのアンロード
crash> extend -u /usr/lib64/crash/extensions/gcore.so
/usr/lib64/crash/extensions/gcore.so: shared object unloaded
```

gcoreがアンロードされたことがわかります。

```console:gcoreの確認
crash> help |grep gcore
crash>
```



##5.4 実行例
ここでは、カーネルのダンプファイルから、httpdのcoreファイルを取り出してみます。

```
crash> ps
 中略
  11037      1   0  ffff8800b9312f70  IN   0.1  221928   4896  httpd
  11038  11037   1  ffff880133620000  IN   0.1  221928   3036  httpd
  11039  11037   3  ffff880133626eb0  IN   0.1  221928   3036  httpd
  11040  11037   2  ffff880133621fa0  IN   0.1  221928   3036  httpd
  11041  11037   1  ffff880036a4dee0  IN   0.1  221928   3036  httpd
  11042  11037   1  ffff880036a4af70  IN   0.1  221928   3036  httpd
```

httpdのcoreファイル生成します。
なぜか、WARNINGが出力されます。なぜでしょう???
原因がわかる方いましたら、教えてください。

```console:httpdのcoreファイル生成
crash> gcore 11037
WARNING: page fault at 55889026b000
(中略)
WARNING: page fault at 7ffff0391000
Saved core.11037.httpd

crash> exit
```

```console:生成したcoreファイルの確認
[root@server ~]# ls -l core.11037.httpd
-rw-r--r--. 1 root root 2215936 12月 24 09:41 core.11037.httpd
```

```console:gdbの起動
[root@server ~]# gdb /usr/sbin/httpd core.11037.httpd
```

```console:httpdのスタック確認結
(gdb) bt
#0  0x00007f6e185af783 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007f6e18cc75a5 in apr_sleep () from /lib64/libapr-1.so.0
#2  0x0000558890012811 in ap_wait_or_timeout (status=0x5, status@entry=0x7ffff03290f8, exitcode=0x7ffff03290fc,
    exitcode@entry=0x1, ret=0xffffffff816b4fc9, ret@entry=0x7ffff0329100, p=<optimized out>, s=<optimized out>)
    at mpm_common.c:195
#3  0x00007f6e0fc060de in prefork_run (_pconf=<optimized out>, plog=<optimized out>, s=<optimized out>)
    at prefork.c:1016
#4  0x0000558890011ffe in ap_run_mpm (pconf=pconf@entry=0x558891fb5158, plog=0x558891fe2378, s=0x558891fde370)
    at mpm_common.c:96
#5  0x000055889000ad76 in main (argc=2, argv=0x7ffff03293f8) at main.c:783
(gdb)
```



#6 ptdumpモジュール
Intel CPUのトレース機能で生成されるログの取り出し、デコード機能を提供します。

##6.1 パッケージのインストール

```console:パッケージのインストール
[root@server ~]# yum -y install crash-ptdump-command
[root@server ~]# rpm -qa|grep crash-ptdump-command
crash-ptdump-command-1.0.3-2.el7.x86_64
```

```console:ptdump.soのインストール先ディレクトリの確認
[root@server ~]# rpm -ql crash-ptdump-command
/usr/lib64/crash/extensions/ptdump.so
/usr/share/doc/crash-ptdump-command-1.0.3
/usr/share/doc/crash-ptdump-command-1.0.3/COPYING
```

##6.2 モジュールのロード

```cosole:crashコマンドの実行
[root@server ~]# crash
```

extendコマンドを実行して、ptdumpモジュールをロードします。

```console:モジュールのロード
crash> extend /usr/lib64/crash/extensions/ptdump.so
/usr/lib64/crash/extensions/ptdump.so: shared object loaded
```

モジュールをロードすると、ヘルプを確認することができるようになります。

```console:ヘルプの確認
crash> help ptdump

NAME
  ptdump - Dump log buffer of Intel(R) Processor Trace

SYNOPSIS
  ptdump <output-dir>

DESCRIPTION
This command extracts log buffer of PT to the directory
specified by <output-dir>
```

##6.3 モジュールのアンロード(-u)

```console:モジュールのアンロード
crash> extend -u /usr/lib64/crash/extensions/ptdump.so
/usr/lib64/crash/extensions/ptdump.so: shared object unloaded
```


#7 traceモジュール
カーネルクラッシュ発生直前のイベントやトレース情報を表示するモジュールです。

##7.1 パッケージのインストール

```console:パッケージのインストール
[root@server ~]# yum -y install crash-trace-command.x86_64
[root@server ~]# rpm -qa|grep crash-trace-command
crash-trace-command-2.0-14.el7.x86_64
```

```console:ptdump.soのインストール先ディレクトリの確認
[root@server ~]# rpm -ql crash-trace-command
/usr/lib64/crash/extensions/trace.so
/usr/share/doc/crash-trace-command-2.0
/usr/share/doc/crash-trace-command-2.0/COPYING
```


##7.2 モジュールのロード

```cosole:crashコマンドの実行
[root@server ~]# crash
```

extendコマンドを実行して、traceモジュールをロードします。

```console:モジュールのロード
crash> extend /usr/lib64/crash/extensions/trace.so
/usr/lib64/crash/extensions/trace.so: shared object loaded
```

```console:ヘルプの確認
crash> help trace

NAME
  trace - show or dump the tracing info

SYNOPSIS
  trace [ <show [-c <cpulist>] [-f [no]<flagname>]> | <dump [-sm] <dest-dir>> ]

(以下、略)
```

##7.3 モジュールのアンロード(-u)

```モジュールのアンロード
crash> extend -u /usr/lib64/crash/extensions/trace.so
/usr/lib64/crash/extensions/trace.so: shared object unloaded
```


#Z 参考情報
[crash extension modules](https://people.redhat.com/anderson/extensions.html)
[How to enable Kdump on RHEL 7 and CentOS 7](https://www.linuxtechi.com/how-to-enable-kdump-on-rhel-7-and-centos-7/)