1. crashの準備
まず、カーネルのシンボル情報の表示などに必要な、dbgsymパッケージ(debuginfo)をインストールする。
dbgsymパッケージはddebs.ubuntu.comで公開されているため、ddebs.ubuntu.comをリポジトリに追加する。
U=http://ddebs.ubuntu.com
D=$(lsb_release -cs)
cat <<EOF | sudo tee /etc/apt/sources.list.d/ddebs.list
deb ${U} ${D} main restricted universe multiverse
#deb ${U} ${D}-security main restricted universe multiverse
deb ${U} ${D}-updates main restricted universe multiverse
deb ${U} ${D}-proposed main restricted universe multiverse
EOF
GPGキーをインポート。
wget -O - http://ddebs.ubuntu.com/dbgsym-release-key.asc | sudo apt-key add -
アップデート&インストール。
sudo apt update -y
sudo apt install linux-image-$(uname -r)-dbgsym -y
kexec-toolsを入れる
sudo apt install kexec-tools -y
Configuring kexec-toolsにはNoと答える
kdump-toolsを入れる
sudo apt install kdump-tools -y
Configuring kdump-toolsはYesと答える
linux-crashdumpを入れる
sudo apt install linux-crashdump -y
次にサービスを確認する。
sudo systemctl status kexec
sudo systemctl status kexec-load
sudo systemctl status kdump-tools
sudo systemctl status kdump-tools-dump
一番下だけstoppedでも正常に動作した。
設定を編集するには次の2つ手法がある
dpkg-reconfigure kdump-tools
sudo vim /etc/default/kdump-tools
設定を編集した後は次のコマンドで更新する必要がある
sudo systemctl stop kdump-tools
kdump-config load
sudo systemctl start kdump-tools
また、/etc/default/grub.d/kdump-tools.cfgを以下のように編集する。
sudo vim /etc/default/grub.d/kdump-tools.cfg
- GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=512M-:192M"
+ GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=384M-2G:64M,2G-:128M"
/etc/default/grub.d/kdump-tools.cfgが存在しない場合は/etc/default/grubを代わりに編集する。
うまくkdumpが動作しない場合は、予約メモリの容量を増やしてみると良い(これで解決するパターンは結構ある)。
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=384M-:512M"
更新する。
sudo update-grub
sudo reboot
現在の設定を見てみる。
sudo kdump-config show
出力:
DUMP_MODE: kdump
USE_KDUMP: 1
KDUMP_SYSCTL: kernel.panic_on_oops=1
KDUMP_COREDIR: /var/crash
crashkernel addr: 0x25000000
/var/lib/kdump/vmlinuz: symbolic link to /boot/vmlinuz-4.15.0-50-generic
kdump initrd:
/var/lib/kdump/initrd.img: symbolic link to /var/lib/kdump/initrd.img-4.15.0-50-generic
current state: ready to kdump
kexec command:
/sbin/kexec -p --command-line="BOOT_IMAGE=/boot/vmlinuz-4.15.0-50-generic root=UUID=a49267ec-7042-11e8-9198-005056ba3e55 ro maybe-ubiquity pti=off maybe-ubiquity nr_cpus=1 systemd.unit=kdump-tools-dump.service irqpoll nousb ata_piix.prefer_ms_hyperv=0" --initrd=/var/lib/kdump/initrd.img /var/lib/kdump/vmlinuz
kdump-configコマンドにはsudoを付けないと、crashkernel addrが正常に表示されないので注意。
sudoで実行しても正しくcrashkernel addrが表示されない場合は何か問題がある。
テストをする。
sysrqが有効になっているか確認。
sudo cat /proc/sys/kernel/sysrq
これが0になっている場合は、無効になっている。
これが1よりも大きな数値になっている場合は、よくわからない感じになっている。
sysrqの有効化。
sudo sysctl -w kernel.sysrq=1
/etc/sysctl.d/99-sysctl.conf
に kernel.sysrq = 1
を書き込んでsysrqの有効化を永続化する。
sudo vim /etc/sysctl.d/99-sysctl.conf
カーネルパニックを発生させる。
sudo su
echo c > /proc/sysrq-trigger
成功すれば、カーネルパニックになった瞬間に再起動が始まり、/var/crash/{timestamp}/以下にダンプファイルが作成される。
ディレクトリ名を変更しておかないといつか消えてしまうので注意。
crash起動
cd /var/crash/20190630901/
sudo crash /usr/lib/debug/boot/vmlinux-$(uname -r) dump.201906030901
2. crash
モジュール関連 (mod, grep)
モジュール一覧取得
crash> mod
...
ffffffffc0625140 coretemp 16384 (not loaded) [CONFIG_KALLSYMS]
ffffffffc06a5580 xxx_mod 110592 (not loaded) [CONFIG_KALLSYMS]
...
grep
crash> mod | grep xxx
ffffffffc06a5580 xxx_mod 110592 (not loaded) [CONFIG_KALLSYMS]
not loadedになっていることがわかる。
モジュールのロードをするためには、まずはmodules.depを生成しなければならない。
depmodについてはこちら。
sudo mkdir -p /lib/modules/$(uname -r)/kernel/drivers/block/xxx
sudo cp -a xxx-mod.ko /lib/modules/$(uname -r)/kernel/drivers/block/xxx/
sudo depmod $(uname -r)
モジュールのロード
crash> mod -s xxx_mod
mod: xxx_mod: last symbol: pmd_to_page is not _MODULE_END_xxx_mod?
MODULE NAME SIZE OBJECT FILE
ffffffffc06a5580 xxx_mod 110592 /lib/modules/4.15.0-50-generic/kernel/drivers/block/xxx/xxx-mod.ko
crash> mod | grep xxx
ffffffffc06a5580 xxx_mod 110592 /lib/modules/4.15.0-50-generic/kernel/drivers/block/xxx/xxx-mod.ko
モジュールのアンロード
crash> mod -d xxx_mod
crash> mod | grep xxx
ffffffffc06a5580 xxx_mod 110592 (not loaded) [CONFIG_KALLSYMS]
一括ロード
crash> mod -S
ネットワーク関連 (net)
net
crash> net
NET_DEVICE NAME IP ADDRESS(ES)
ffff8f24acd08000 lo 127.0.0.1
ffff8f249d3e4000 ens160 10.224.146.206
arpキャッシュ
crash> net -a
NEIGHBOUR IP ADDRESS HW TYPE HW ADDRESS DEVICE STATE
ffff8f249fe4fe00 0.0.0.0 UNKNOWN 00 00 00 00 00 00 lo NOARP
ffff8f24a800c000 10.224.144.1 ETHER 10:05:ca:a3:e3:4a ens160 STALE
ffff8f249d26f400 10.224.146.1 ETHER 00:50:56:a2:23:38 ens160 STALE
プロセスがopenしているソケットの情報を表示
crash> net -s <PID>
PID: 4364 TASK: ffff880031f62f10 CPU: 0 COMMAND: "nc"
FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
3 ffff8800390e5000 ffff880035ee8000 INET6:STREAM
4 ffff8800390e3c00 ffff88003b3d3640 INET:STREAM 0.0.0.0-11111 0.0.0.0-0
数値をIPアドレスに変換
crash> net -N 1041236234
10.1.16.62
特定の条件で絞り込み(説明略)
crash> foreach net -s -R 3
逆アセンブル (dis)
逆アセンブル
crash> dis do_fork
0xffffffff81084950 <do_fork>: data32 data32 data32 xchg %ax,%ax [FTRACE NOP]
0xffffffff81084955 <do_fork+5>: push %rbp
0xffffffff81084956 <do_fork+6>: mov %rsp,%rbp
0xffffffff81084959 <do_fork+9>: push %r15
0xffffffff8108495b <do_fork+11>: push %r14
0xffffffff8108495d <do_fork+13>: xor %r14d,%r14d
...
逆アセンブルとソースコードの行番号を照らし合わせる
crash> dis -l do_fork
/usr/src/debug/kernel-3.10.0-514.el7/linux-3.10.0-514.el7.x86_64/kernel/fork.c: 1690
0xffffffff81084950 <do_fork>: data32 data32 data32 xchg %ax,%ax [FTRACE NOP]
0xffffffff81084955 <do_fork+5>: push %rbp
0xffffffff81084956 <do_fork+6>: mov %rsp,%rbp
0xffffffff81084959 <do_fork+9>: push %r15
0xffffffff8108495b <do_fork+11>: push %r14
/usr/src/debug/kernel-3.10.0-514.el7/linux-3.10.0-514.el7.x86_64/kernel/fork.c: 1692
0xffffffff8108495d <do_fork+13>: xor %r14d,%r14d
...
ソースコード表示
crash> dis -s do_fork
FILE: kernel/fork.c
LINE: 1690
1685 long do_fork(unsigned long clone_flags,
1686 unsigned long stack_start,
1687 unsigned long stack_size,
1688 int __user *parent_tidptr,
1689 int __user *child_tidptr)
* 1690 {
1691 struct task_struct *p;
1692 int trace = 0;
1693 long nr;
...
関数呼び出しの箇所を探す
crash> dis -l neigh_probe
/usr/src/debug/kernel-3.10.0-514.el7/linux-3.10.0-514.el7.x86_64/net/core/neighbour.c: 869
0xffffffff8157b1e0 <neigh_probe>: data32 data32 data32 xchg %ax,%ax [FTRACE NOP]
0xffffffff8157b1e5 <neigh_probe+5>: push %rbp
...
0xffffffff8157b222 <neigh_probe+66>: callq *0x8(%rax) <==★
crash> dis -s 0xffffffff8157b222
FILE: net/core/neighbour.c
LINE: 875
870 struct sk_buff *skb = skb_peek(&neigh->arp_queue);
871 /* keep skb alive even if arp_queue overflows */
872 if (skb)
873 skb = skb_copy(skb, GFP_ATOMIC);
874 write_unlock(&neigh->lock);
* 875 ★neigh->ops->solicit(neigh, skb);
876 atomic_inc(&neigh->probes);
877 kfree_skb(skb);
878 }
データ調査 (whatis, rb)
変数の調査
crash> whatis vmap_area_root
struct rb_root vmap_area_root;
構造体の調査
crash> whatis rb_root
struct rb_root {
struct rb_node *rb_node;
}
SIZE: 8
変数のアドレス表示
crash> rd vmap_area_root
ffffffff8b4637d0: ffff8f24a6d626d8 .&..$...
構造体のオフセット調査
crash> whatis -o vmap_area
struct vmap_area {
[0] unsigned long va_start;
[8] unsigned long va_end;
[16] unsigned long flags;
[24] struct rb_node rb_node;
[48] struct list_head list;
crash> whatis -o vmap_area | grep rb_node
[24] struct rb_node rb_node;
データ調査 (tree)
vmap_area 構造体を管理する rbtree (red black tree) の root ノードを指す変数である vmap_area_root の調査 (各ノードは vmap_area.rb_node である)
crash> tree -t rbtree -o vmap_area.rb_node vmap_area_root -p
ffff8f24a6d626c0
position: root
ffff8f24a10156c0
position: root/l
ffff8f249d2925a0
position: root/l/l
ffff8f249dd021e0
position: root/l/l/l
...
ffff8f24af0579c0
position: root/l/l/l/l/l/l/l/l/r
ffff8f24af057c60
position: root/l/l/l/l/l/l/l/r
ffff8f24ad17e6c0
position: root/l/l/l/l/l/l/l/r/l
ffff8f24af0578a0
position: root/l/l/l/l/l/l/l/r/l/l
...
vmap_area構造体の特定のメンバを調査
crash> tree -t rbtree -o vmap_area.rb_node vmap_area_root -s vmap_area.va_start,va_end -x
ffff8f24a6d626c0
va_start = 0xffffae4884188000
va_end = 0xffffae488418d000
ffff8f24a10156c0
va_start = 0xffffae48837b8000
va_end = 0xffffae48837bd000
ffff8f249d2925a0
va_start = 0xffffae4882034000
va_end = 0xffffae4882039000
...
データ調査 (list)
file_system_type という構造体 (next メンバが fd) が繋がっている一方向リンクリストを調査 (先頭アドレスは file_systems というポインタ変数に格納されている)
crash> rd file_systems
ffffffff8b4c0688: ffffffff8af3c040 @.......
crash> list file_system_type.next -s file_system_type.name,fs_flags ffffffff8af3c040
ffffffff8af3c040
name = 0xffffffff8ab2cefe "sysfs"
fs_flags = 8
ffffffff8ae12440
name = 0xffffffff8aaf7a37 "rootfs"
fs_flags = 0
ffffffff8af47fc0
name = 0xffffffff8aab830f "ramfs"
fs_flags = 8
...
双方向リンクリストを調査する場合は fd の部分を fd, bk をもつ構造体の名前に変更し、先頭アドレスを -h オプションの引数に指定するだけ。
crash> list task_struct.tasks -s task_struct.comm -h ffffffff8ae12480
ffffffff8ae12480
comm = "swapper/0\000\000\000\000\000\000"
ffff8f24ad685b00
comm = "systemd\000\000\000\000\000\000\000\000"
ffff8f24ad680000
...
プロセスコンテキストの調査 (set, ps, bt)
引数無しで実行すると現在のプロセスコンテキストを調査することができる
crash> set
PID: 0
COMMAND: "swapper/0"
TASK: ffffffff8ae12480 (1 of 8) [THREAD_INFO: ffffffff8ae12480]
CPU: 0
STATE: TASK_RUNNING (PANIC)
プロセス一覧を表示
ここで各プロセスのPIDを確認する
PID PPID CPU TASK ST %MEM VSZ RSS COMM
> 0 0 0 ffffffff8ae12480 RU 0.0 0 0 [swapper/0]
> 0 0 1 ffff8f24ad6e2d80 RU 0.0 0 0 [swapper/1]
> 0 0 2 ffff8f24ad6e4440 RU 0.0 0 0 [swapper/2]
> 0 0 3 ffff8f24ad6e5b00 RU 0.0 0 0 [swapper/3]
> 0 0 4 ffff8f24ad6e0000 RU 0.0 0 0 [swapper/4]
> 0 0 5 ffff8f24ad6e96c0 RU 0.0 0 0 [swapper/5]
> 0 0 6 ffff8f24ad6ead80 RU 0.0 0 0 [swapper/6]
> 0 0 7 ffff8f24ad6ec440 RU 0.0 0 0 [swapper/7]
1 0 0 ffff8f24ad685b00 IN 0.1 225876 9644 systemd
2 0 4 ffff8f24ad680000 IN 0.0 0 0 [kthreadd]
3 2 0 ffff8f24ad6816c0 UN 0.0 0 0 [kworker/0:0]
4 2 0 ffff8f24ad682d80 UN 0.0 0 0 [kworker/0:0H]
6 2 0 ffff8f24ad6b8000 UN 0.0 0 0 [mm_percpu_wq]
7 2 0 ffff8f24ad6b96c0 IN 0.0 0 0 [ksoftirqd/0]
8 2 6 ffff8f24ad6bad80 UN 0.0 0 0 [rcu_sched]
9 2 0 ffff8f24ad6bc440 UN 0.0 0 0 [rcu_bh]
...
第1引数にPIDを指定することでプロセスコンテキストを変更することができる
crash> set 1
PID: 1
COMMAND: "systemd"
TASK: ffff88003bec8000 [THREAD_INFO: ffff88003bed0000]
CPU: 0
STATE: TASK_INTERRUPTIBLE
バックトレースを表示
crash> bt
PID: 0 TASK: ffffffff8ae12480 CPU: 0 COMMAND: "swapper/0"
#0 [ffff8f24bfc03c40] machine_kexec at ffffffff89a63ee3
#1 [ffff8f24bfc03ca0] __crash_kexec at ffffffff89b2bf59
#2 [ffff8f24bfc03d68] crash_kexec at ffffffff89b2ccc1
#3 [ffff8f24bfc03d88] oops_end at ffffffff89a30df8
#4 [ffff8f24bfc03db0] die at ffffffff89a314c2
#5 [ffff8f24bfc03de0] do_general_protection at ffffffff89a2da7d
#6 [ffff8f24bfc03e10] general_protection at ffffffff8a401575
[exception RIP: run_timer_softirq+864]
RIP: ffffffff89b0b010 RSP: ffff8f24bfc03ec8 RFLAGS: 00010086
RAX: dead000000000200 RBX: ffff8f24bfc1a700 RCX: ffff8f24bfc03ed8
RDX: 0000000000000100 RSI: ffff8f24bfc1a728 RDI: 0000000000000008
RBP: ffff8f24bfc03f50 R8: ffff8f24bfc03ee0 R9: ffff8f24bfc1af30
R10: ffff8f24bfc03ee0 R11: ffff8f24bfc1a770 R12: ffff8f24bfc03ed8
R13: dead000000000200 R14: 0000000000000001 R15: ffff8f24a2dd1dd0
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#7 [ffff8f24bfc03ec0] run_timer_softirq at ffffffff89b0af18
#8 [ffff8f24bfc03f58] __softirqentry_text_start at ffffffff8a6000e4
#9 [ffff8f24bfc03fc0] irq_exit at ffffffff89a947f8
#10 [ffff8f24bfc03fd0] smp_apic_timer_interrupt at ffffffff8a402dd9
#11 [ffff8f24bfc03ff0] apic_timer_interrupt at ffffffff8a401ff4
--- <IRQ stack> ---
#12 [ffffffff8ae03d50] apic_timer_interrupt at ffffffff8a401ff4
[exception RIP: unknown or invalid address]
RIP: 0000000000000000 RSP: 0000000000000000 RFLAGS: 00000000
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000082
RDX: ffffffff8ae03dc8 RSI: 0000000000000000 RDI: 0000000000000002
RBP: ffffffff8a4001a0 R8: ffffffff8ae03e28 R9: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8a400194
R13: ffffffff8a4001a0 R14: ffffffff8a400194 R15: ffffffff8a4001a0
ORIG_RAX: ffffffff8a3a2110 CS: 0000 SS: ffffffffffffff11
bt: WARNING: possibly bogus exception frame
#13 [ffffffff8ae03df8] native_safe_halt at ffffffff8a3a2472
#14 [ffffffff8ae03e30] default_idle at ffffffff8a3a2130
#15 [ffffffff8ae03e58] arch_cpu_idle at ffffffff89a39025
#16 [ffffffff8ae03e68] default_idle_call at ffffffff8a3a2603
#17 [ffffffff8ae03e78] do_idle at ffffffff89ad4b12
#18 [ffffffff8ae03ea8] cpu_startup_entry at ffffffff89ad4d73
#19 [ffffffff8ae03ed0] rest_init at ffffffff8a394d3e
#20 [ffffffff8ae03ee0] start_kernel at ffffffff8b0a50d6
#21 [ffffffff8ae03f28] x86_64_start_reservations at ffffffff8b0a44d2
#22 [ffffffff8ae03f38] x86_64_start_kernel at ffffffff8b0a4548
#23 [ffffffff8ae03f50] secondary_startup_64 at ffffffff89a000d5
task_struct構造体の調査 (task)
現在のプロセスコンテキストの task_struct を表示
crash> task
PID: 0 TASK: ffffffff8ae12480 CPU: 0 COMMAND: "swapper/0"
struct task_struct {
thread_info = {
flags = 2147483648,
status = 0
},
...
現在のプロセスコンテキストの task_struct.state と task_struct.stack を表示
crash> task -R state,stack
PID: 0 TASK: ffffffff8ae12480 CPU: 0 COMMAND: "swapper/0"
state = 0,
stack = 0xffffffff8ae00000,
現在のプロセスコンテキストの task_struct.se.on_rq を表示
crash> task -R se.on_rq
PID: 0 TASK: ffffffff8ae12480 CPU: 0 COMMAND: "swapper/0"
se.on_rq = 0,
ファイル関連 (files, fuser)
プロセスごとに関係のある /var/log 以下のファイル一覧を表示
crash> foreach files -R /var/log
PID: 551 TASK: ffff8f249cd8db00 CPU: 4 COMMAND: "vmtoolsd"
ROOT: / CWD: /
FD FILE DENTRY INODE TYPE PATH
3 ffff8f24a07ada00 ffff8f249e2ee300 ffff8f24ac71d5e8 REG /var/log/vmware-vmsvc.log
PID: 552 TASK: ffff8f249cd116c0 CPU: 5 COMMAND: "systemd-journal"
ROOT: / CWD: /
FD FILE DENTRY INODE TYPE PATH
20 ffff8f249f673700 ffff8f24a096cc00 ffff8f24a20933e8 REG /var/log/journal/eeb4c85c6e7542f7995c6e87999275e4/system@4398f41d8f674d07839cef96fcc6637c-0000000000000001-00058a671e796c61.journal
32 ffff8f24a0534800 ffff8f24aadc56c0 ffff8f24aa9f0968 REG /var/log/journal/eeb4c85c6e7542f7995c6e87999275e4/system.journal
36 ffff8f24a140cd00 ffff8f24aa568900 ffff8f24a08177e8 REG /var/log/journal/eeb4c85c6e7542f7995c6e87999275e4/user-1000.journal
プロセスごとに関係のある TCP ソケットファイルの一覧表示
TCP の他にも UDP, NETLINK, UNIX などを指定できる。
crash> foreach files -R TCP
PID: 1169 TASK: ffff8f249cd8c440 CPU: 5 COMMAND: "systemd-resolve"
ROOT: / CWD: /
FD FILE DENTRY INODE TYPE PATH
13 ffff8f24a82cd600 ffff8f24abbead80 ffff8f24abbccb30 SOCK TCP
PID: 1697 TASK: ffff8f249e9fad80 CPU: 0 COMMAND: "sshd"
ROOT: / CWD: /
FD FILE DENTRY INODE TYPE PATH
3 ffff8f24a1f26400 ffff8f24aac663c0 ffff8f24aae09bb0 SOCK TCP
4 ffff8f24a1f26b00 ffff8f24aac66180 ffff8f24aae0a130 SOCK TCPv6
...
指定したファイルと関係のあるプロセスを表示
ファイル名の代わりにinode番号を指定することもできる。
crash> fuser /var/log/vmware-vmsvc.log
PID TASK COMM USAGE
551 ffff8f249cd8db00 "vmtoolsd" fd
シンボル関連 (sym)
シンボル一覧を表示
crash> sym -l
0 (D) __per_cpu_start
0 (D) irq_stack_union
4000 (D) cpu_debug_store
5000 (D) cpu_tss_rw
8000 (D) gdt_page
9000 (d) exception_stacks
...
モジュール指定
crash> sym -m xxx_mod
ffffffffc0690000 MODULE START: xxx_mod
ffffffffc0690000 (t) xxx_open
ffffffffc0690030 (t) xxx_release
ffffffffc0690050 (t) xxxlog_open
...
文字列指定
crash> sym -q super
ffffffff89a3bfc2 (t) xfeature_is_supervisor
ffffffff89bacbe0 (t) bpf_fill_super
ffffffff89bf08b0 (t) shmem_put_super
ffffffff89bf1800 (T) shmem_fill_super
ffffffff89c7b090 (t) ns_test_super
前後表示 (説明略)
crash> sym -p ip_forward
crash> sym -n ip_forward
その他 (swap, repeat)
swapデバイスの情報を表示
crash> swap
SWAP_INFO_STRUCT TYPE SIZE USED PCT PRI FILENAME
ffff8f24a74f0000 FILE 4194300k 0k 0% -2 /swap.img
説明略
crash> set scroll off
crash> ps chronyd
crash> set 505
crash> repeat -2 files
3. 参考URL
- https://qiita.com/saikoro-steak/items/c61f3d9b6384836f8e80
- https://users.miraclelinux.com/support/files/u1/OSC2008_Spring_dumpver1_1.pdf
- https://askubuntu.com/questions/818675/how-can-i-reboot-extra-fast/833177
- http://shareithw.blogspot.com/2017/05/ubuntu-kdump-ppc64le.html
- http://deletefrom.hateblo.jp/entry/20140415/1397582169
- https://help.ubuntu.com/lts/serverguide/kernel-crash-dump.html.en
- https://qiita.com/hana_shin/items/02d8da181c8287580613