Ubuntu Weekly Recipe

第674回カーネルのクラッシュ情報を解析する

第673回のカーネルのクラッシュ情報を取得するでは、カーネルクラッシュ時に情報を収集する仕組みを有効化しました。得られた情報は活用しないと意味がありません。今回はその中身を解析する方法を紹介します。

デバッグパッケージのインストール

第673回では、意図的にシステムをクラッシュさせることで、dmesgとvmcoreを取得しました。カーネルが今際の際に次につながる情報を残してくれたのです。⁠しかしながらあのクラッシュが最後のpanicだとは思えない。もし、同じカーネルが続けて使われるとしたら、あのpanicの同類が、また世界のどこかへ現れてくるかもしれない……」

最初に行うべきなのは、前回紹介したように問題発生時のdmesgを読むことです。これである程度、状況の絞り込みは行えますし、運が良ければ原因がわかることもあります。しかしながら、dmesgだけだと「問題が起きた場所」はわかっても、⁠なぜそこで問題が起きたのか」まではわからないことも多いです。そこで利用できるのがクラッシュダンプです。これは現象発生したあと、実際にpanicが発生したタイミングでのカーネルメモリーの内容が保存されています。つまり、実行中のタスクは何かや、他のタスクの状態、各種変数の内容などを一通り確認できるのです。

というわけで第673回で取得した、クラッシュダンプの内容を精査しましょう。第673回ではsysrq-triggerを用いて意図的にクラッシュさせて、/var/crash/以下にdmesgとクラッシュダンプ(vmcoreファイル)を取得していました。今回解析するのはこのクラッシュダンプのほうです。解析にはcrashコマンドを利用します。crashはカーネルダンプの調査に特化した、gdbのラッパーツールです。

ただしカーネルをデバッガで調査するのであれば、vmlinuxやstripされていないカーネルモジュール群が必要です。実はこれらのファイルは非常にサイズが大きいため、通常のリポジトリには置かれていません。デバッグシンボル用のリポジトリを取り込む必要があります。まずは次のコマンドで、リポジトリを有効化してください。

$ sudo apt install ubuntu-dbgsym-keyring
$ sudo tee /etc/apt/sources.list.d/ddebs.list << EOF
deb http://ddebs.ubuntu.com/ $(lsb_release -cs)          main restricted universe multiverse
deb http://ddebs.ubuntu.com/ $(lsb_release -cs)-updates  main restricted universe multiverse
deb http://ddebs.ubuntu.com/ $(lsb_release -cs)-proposed main restricted universe multiverse
EOF
$ sudo apt update

ちなみに上記はUbuntu 18.04 LTS以降でのみ有効です。18.04より前にはubuntu-dbgsym-keyringパッケージがないため、リポジトリにある鍵を別途取り込むようにしてください。また今回の手順はUbuntuのリリースカーネルにのみ有効です。Mainlineビルドや、その他サードパーティのカーネルの場合は、別の手段でデバッグシンボル付きカーネルを入手してください[1]⁠。

さて、今回は現在実行中のカーネルのデバッグパッケージをインストールしましょう。

$ sudo apt install linux-image-$(uname -r)-dbgsym

おそらく1GiBほどのサイズをダウンロードすることになるので注意してください。またクラッシュダンプ取得時のカーネルバージョンが、実行中のカーネルではない$(uname -r)の部分を適宜書き換えてください。クラッシュダンプのカーネルバージョンは、たとえばdmesgファイルの以下の部分で確認可能です。

[ 6262.530045] CPU: 3 PID: 111191 Comm: tee Kdump: loaded Tainted: G S       C  E     5.11.0-22-generic #23-Ubuntu

ここの5.11.0-22-generic$(uname -r)のそれに該当します。

ちなみにcrashコマンドとデバッグパッケージさえ用意できるなら、⁠クラッシュが発生したマシン」である必要はありません。運用中のサーバーはそのままクラッシュ情報収集したら、再度運用に戻して、別のマシンで解析することも可能です。

なお、別のアーキテクチャーの解析は、Ubuntuのcrashコマンドではできません。たとえば、Raspberry Piで発生したクラッシュダンプは、x86マシンでは解析できないのです。ただしこれはUbuntuのcrashコマンドのビルド方法に起因するものであり、crashコマンドを自前でクロスビルドするなら、別アーキテクチャーのダンプを解析することは可能です。

クラッシュダンプの解析

crashコマンドを使ってクラッシュダンプを解析するには「デバッグ用のカーネル本体」「対象のvmcoreファイル」が必要になります。このうちデバッグパッケージによってインストールされるデバッグ用のカーネル一式は/usr/lib/debug以下にダウンロードされます。そこで、次のようなコマンドでcrashマンドを起動しましょう。

$ crash /usr/lib/debug/boot/vmlinux-5.11.0-22-generic /var/crash/202107040335/dump.202107040335

crash 7.2.9
(中略)
GNU gdb (GDB) 7.6
(中略)

      KERNEL: /usr/lib/debug/boot/vmlinux-5.11.0-22-generic
    DUMPFILE: 202107040335/dump.202107040335  [PARTIAL DUMP]
        CPUS: 4
        DATE: Sun Jul  4 03:34:41 JST 2021
      UPTIME: 00:29:50
LOAD AVERAGE: 0.38, 0.18, 0.09
       TASKS: 475
    NODENAME: ubuntu-ax2
     RELEASE: 5.11.0-22-generic
     VERSION: #23-Ubuntu SMP Thu Jun 17 00:34:23 UTC 2021
     MACHINE: x86_64  (1695 Mhz)
      MEMORY: 3.9 GB
       PANIC: "Kernel panic - not syncing: sysrq triggered crash"
         PID: 111191
     COMMAND: "tee"
        TASK: ffff8b4702b3b080  [THREAD_INFO: ffff8b4702b3b080]
         CPU: 3
       STATE: TASK_RUNNING (PANIC)

crash>

第一引数がvmlinuxファイルで、第二引数がクラッシュダンプイメージです。システムによってはロードに時間がかかるかもしれません。必要なファイルが揃っているなら、上記のように情報が表示されるはずです。上記の内容自体は、dmesgファイルにもある情報ですね。teeコマンドによるタスクがCPU 3で動いているときに、sysrq-triggerによってpanicしたことがわかります。

crashをうまく起動できたら、あとは普通のデバッガとして使うだけです。たとえばバックトレースなら次のように表示できます。

crash> bt
PID: 111191  TASK: ffff8b4702b3b080  CPU: 3   COMMAND: "tee"
 #0 [ffffa2cd898cfc80] machine_kexec at ffffffffa1a77b63
 #1 [ffffa2cd898cfce0] __crash_kexec at ffffffffa1b66a42
 #2 [ffffa2cd898cfdb0] panic at ffffffffa25dd1a3
 #3 [ffffa2cd898cfe30] sysrq_handle_crash at ffffffffa2160bfa
 #4 [ffffa2cd898cfe40] __handle_sysrq.cold at ffffffffa26094b6
 #5 [ffffa2cd898cfe78] write_sysrq_trigger at ffffffffa21615f8
 #6 [ffffa2cd898cfe90] proc_reg_write at ffffffffa1dcc6ca
 #7 [ffffa2cd898cfeb0] vfs_write at ffffffffa1d1eb76
 #8 [ffffa2cd898cfee8] ksys_write at ffffffffa1d21277
 #9 [ffffa2cd898cff28] __x64_sys_write at ffffffffa1d2130a
#10 [ffffa2cd898cff38] do_syscall_64 at ffffffffa2636ab8
#11 [ffffa2cd898cff50] entry_SYSCALL_64_after_hwframe at ffffffffa280008c
    RIP: 00007f3a4110cc27  RSP: 00007ffeb514fbd8  RFLAGS: 00000246
    RAX: ffffffffffffffda  RBX: 0000000000000002  RCX: 00007f3a4110cc27
    RDX: 0000000000000002  RSI: 00007ffeb514fcc0  RDI: 0000000000000003
    RBP: 00007ffeb514fcc0   R8: 0000000000000002   R9: 0000000000000001
    R10: 00000000000001b6  R11: 0000000000000246  R12: 0000000000000002
    R13: 00005622844eb4e0  R14: 0000000000000002  R15: 00007f3a411e68a0
    ORIG_RAX: 0000000000000001  CS: 0033  SS: 002b
crash>

このあたりはdmesgで表示されているものと同じですね。タスクのリストはpsコマンドで確認できます。

crash> ps
   PID    PPID  CPU       TASK        ST  %MEM     VSZ    RSS  COMM
>     0      0   0  ffffffffa361a940  RU   0.0       0      0  [swapper/0]
>     0      0   1  ffff8b4800a81840  RU   0.0       0      0  [swapper/1]
      0      0   2  ffff8b4800a86100  RU   0.0       0      0  [swapper/2]
      0      0   3  ffff8b4800a848c0  RU   0.0       0      0  [swapper/3]
      1      0   1  ffff8b4800276100  IN   0.2  165012  11152  systemd
(中略)
   3755   3746   1  ffff8b4727169840  IN   1.2  496448  57560  dconf worker
   3761   3750   0  ffff8b47029a8000  IN   0.1   19476   3928  tmux: client
>  3797   3191   2  ffff8b4702b2b080  RU   0.1   20136   4244  tmux: server
   3805   3797   3  ffff8b47029ab080  IN   0.1   21328   6076  bash
(中略)
  110886   3191   2  ffff8b4727766100  IN   0.5  372332  23340  pool-tracker-st
  111190   3805   1  ffff8b473b840000  IN   0.1   24104   6004  sudo
> 111191  111190   3  ffff8b4702b3b080  RU   0.0   18008   2048  tee

>が付いているのが実行中のタスクです。上記は2コア4スレッドのCPUなので、4個表示されています。たとえばtmuxサーバーが動いていたPID=3797の情報は次のように表示できます。

crash> bt 3797
PID: 3797   TASK: ffff8b4702b2b080  CPU: 2   COMMAND: "tmux: server"
 #0 [ffffa2cd8127fe88] crash_nmi_callback at ffffffffa1a6a997
 #1 [ffffa2cd8127fe98] nmi_handle at ffffffffa1a38d29
 #2 [ffffa2cd8127fee8] default_do_nmi at ffffffffa2638367
 #3 [ffffa2cd8127ff18] exc_nmi at ffffffffa26385db
 #4 [ffffa2cd8127ff50] asm_exc_nmi at ffffffffa28014c3
    RIP: 00007f989b16aad9  RSP: 00007ffd8ceb0590  RFLAGS: 00000206
    RAX: 0000563e6009d430  RBX: 0000000000000000  RCX: 0000000000000000
    RDX: 0000000000000000  RSI: 0000000000000000  RDI: 0000000000000000
    RBP: 0000563e600f3468   R8: 0000000000000003   R9: 0000000000000001
    R10: 0000000000000003  R11: 0000000000000000  R12: 0000563e600f3468
    R13: 0000000000000000  R14: 0000563e600f3468  R15: 0000563e6009d430
    ORIG_RAX: ffffffffffffffff  CS: 0033  SS: 002b

crash> task 3797
PID: 3797   TASK: ffff8b4702b2b080  CPU: 2   COMMAND: "tmux: server"
struct task_struct {
  thread_info = {
    flags = 0,
    syscall_work = 0,
    status = 0
  },
(後略)

psやtaskのように行数が多い場合はページャー経由での表示になります。もしページャーを無効化したい場合はset scroll offを実行してください。

グローバル変数などはpコマンドで内容を確認できます。またアドレスがわかっていれば、シンボル名指定以外の方法も可能です。

crash> p jiffies
jiffies = $1 = 4296457959
crash> p vermagic
vermagic = $2 = "5.11.0-22-generic SMP mod_unload modversions "

タスクごとのファイルディスクリプター一覧は次のように確認できます。

crash> files 732
PID: 732    TASK: ffff8b480defb080  CPU: 2   COMMAND: "NetworkManager"
ROOT: /    CWD: /
 FD       FILE            DENTRY           INODE       TYPE PATH
  0 ffff8b480d2b7f00 ffff8b4800462240 ffff8b48010cd420 CHR  /dev/null
  1 ffff8b48077a3600 ffff8b4803c15180 ffff8b48085fca40 SOCK UNIX
  2 ffff8b48077a3600 ffff8b4803c15180 ffff8b48085fca40 SOCK UNIX
  3 ffff8b48077ef500 ffff8b4803c689c0 ffff8b4801a98be0 UNKN [eventfd]
  4 ffff8b4807b09b00 ffff8b4803d04480 ffff8b4801a98be0 UNKN [eventfd]
  5 ffff8b4807b09600 ffff8b4803d046c0 ffff8b4803d46e00 SOCK UNIX
  6 ffff8b4807339300 ffff8b4803c47d80 ffff8b4803d44080 SOCK UNIX
  7 ffff8b48023e3300 ffff8b4803d603c0 ffff8b4801a98be0 UNKN [eventfd]
  8 ffff8b480735b800 ffff8b4803ce5b40 ffff8b4803ba84c0 REG  /
  9 ffff8b480735be00 ffff8b4803cfe480 ffff8b4803c1b1e0 REG  /
 10 ffff8b48073aff00 ffff8b4803cfea80 ffff8b4803d26ac0 SOCK NETLINK
 11 ffff8b48073af100 ffff8b4803cfe840 ffff8b4803d25a80 SOCK NETLINK
 12 ffff8b48073af300 ffff8b4803cfeb40 ffff8b4803d26780 SOCK NETLINK
 13 ffff8b480c344700 ffff8b4803d67180 ffff8b4801a98be0 UNKN inotify
 14 ffff8b4809f39900 ffff8b4803d67c00 ffff8b4801a98be0 UNKN inotify
 15 ffff8b480dc0c100 ffff8b473c5ecd80 ffff8b480e2cca40 SOCK NETLINK
 16 ffff8b473c100a00 ffff8b473c5ed000 ffff8b473c64ca40 SOCK NETLINK
 17 ffff8b470289e700 ffff8b4703c57b40 ffff8b4801a98be0 UNKN [eventpoll]
 18 ffff8b4809205500 ffff8b473c7fe180 ffff8b47396048e0 FIFO /run/systemd/inhibit/systemd/inhibit/3.ref
 19 ffff8b4702b61900 ffff8b4714818600 ffff8b4801a98be0 UNKN [eventpoll]
 20 ffff8b4702b61200 ffff8b47148189c0 ffff8b4801a98be0 UNKN [timerfd]
 21 ffff8b4719513700 ffff8b473c749e40 ffff8b47149d2e00 SOCK RAWv6
 22 ffff8b4702b61700 ffff8b4714818f00 ffff8b473c785dc0 SOCK UDPv6
 23 ffff8b4702b61800 ffff8b4714818540 ffff8b473c784a40 SOCK PACKET
 24 ffff8b473c39d700 ffff8b4720aab180 ffff8b473c786440 SOCK UDP
 25 ffff8b471ce4da00 ffff8b4714baaa80 ffff8b4801a98be0 UNKN [timerfd]

crashでは他にもさまざまなコマンドで、情報を確認できます。詳細はhelpコマンドやhelpページを参照してください。

ソースコードも参照できるようにする

GDBと同じように、crashコマンドでも解析箇所のソースコードの情報を表示できます。そのためにはまずカーネルのソースコードを入手する必要があります。

crash> dis write_sysrq_trigger
0xffffffffa21615d0 <write_sysrq_trigger>:       nopl   0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffffa21615d5 <write_sysrq_trigger+5>:     push   %rbp
0xffffffffa21615d6 <write_sysrq_trigger+6>:     mov    %rsp,%rbp
0xffffffffa21615d9 <write_sysrq_trigger+9>:     push   %rbx
0xffffffffa21615da <write_sysrq_trigger+10>:    mov    %rdx,%rbx
0xffffffffa21615dd <write_sysrq_trigger+13>:    test   %rdx,%rdx
0xffffffffa21615e0 <write_sysrq_trigger+16>:    je     0xffffffffa21615f8 <write_sysrq_trigger+40>
0xffffffffa21615e2 <write_sysrq_trigger+18>:    mov    %rsi,%rax
0xffffffffa21615e5 <write_sysrq_trigger+21>:    callq  0xffffffffa20238f0 <__get_user_1>
0xffffffffa21615ea <write_sysrq_trigger+26>:    test   %eax,%eax
0xffffffffa21615ec <write_sysrq_trigger+28>:    jne    0xffffffffa2161601 <write_sysrq_trigger+49>
0xffffffffa21615ee <write_sysrq_trigger+30>:    movsbl %dl,%edi
0xffffffffa21615f1 <write_sysrq_trigger+33>:    xor    %esi,%esi
0xffffffffa21615f3 <write_sysrq_trigger+35>:    callq  0xffffffffa2161110 <__handle_sysrq>
0xffffffffa21615f8 <write_sysrq_trigger+40>:    mov    %rbx,%rax
0xffffffffa21615fb <write_sysrq_trigger+43>:    mov    -0x8(%rbp),%rbx
0xffffffffa21615ff <write_sysrq_trigger+47>:    leaveq
0xffffffffa2161600 <write_sysrq_trigger+48>:    retq
0xffffffffa2161601 <write_sysrq_trigger+49>:    mov    $0xfffffffffffffff2,%rax
0xffffffffa2161608 <write_sysrq_trigger+56>:    jmp    0xffffffffa21615fb <write_sysrq_trigger+43>
0xffffffffa216160a <write_sysrq_trigger+58>:    int3
0xffffffffa216160b <write_sysrq_trigger+59>:    int3
0xffffffffa216160c <write_sysrq_trigger+60>:    int3
0xffffffffa216160d <write_sysrq_trigger+61>:    int3
0xffffffffa216160e <write_sysrq_trigger+62>:    int3
0xffffffffa216160f <write_sysrq_trigger+63>:    int3

Ubuntuでカーネルのソースコードを入手するには主に3種類の方法が存在します。

  1. Kernel Teamのgitリポジトリからリリースごとの最新のコードをcloneする
  2. sudo apt install linux-sourceを実行する
  3. apt source linux-image-unsigned-$(uname -r)を実行する

開発版も含めて最新のソースコードの変更履歴が必要な場合は1を使います。リポジトリ名は「ubuntu/ubuntu-focal.git」のような名前になっているので、それを検索すると良いでしょう。ただしこれは大抵の場合、実行中のカーネルのソースコードとは必ずしも一致しないので注意が必要です。

リポジトリからインストールできるカーネルパッケージの最新版で問題が起きているのであれば、2の方法でソースコードを取得できます。この方法の利点のひとつは、linux-sourceパッケージは常に最新のカーネルバージョンに向いているため、新しいバージョンがリリースされたら自動的に新しいソースコードも入手できる点です。逆に言うと、古いカーネルバージョンで問題が起きている場合、この方法では該当するソースコードを取得できません。

特定のカーネルパッケージのバージョンのソースコードを取得したいなら、3の方法が確実です。ただしこれを実行するためにはソースパッケージリポジトリを有効化しておく必要があり、さらにソースコードパッケージを展開できなくてはなりません。今回はこの方法を紹介します。

まずはソースパッケージリポジトリの有効化方法です。デスクトップ版なら「ソフトウェアとアップデート」を起動して、⁠Ubuntuのソフトウェア」タブの「ソースコード」にチェックを入れるだけです。サーバー版なら、次のように/etc/apt/sources.listのdeb-srcの行を有効化しましょう。

$ sudo sed -i 's/^# \(deb-src.*ubuntu.com.*\)$/\1/'  /etc/apt/sources.list
$ sudo apt update
$ sudo apt dpkg-dev

最後のdpkg-devパッケージは、ソースパッケージを展開するために必要なパッケージです。次に適当なディレクトリを作成し、そこにソースパッケージをダウンロードします。

$ mkdir -p ~/Packages/linux && cd $_
$ apt source linux-image-unsigned-$(uname -r)
$ ls
linux-5.11.0  linux_5.11.0-22.23.diff.gz  linux_5.11.0-22.23.dsc  linux_5.11.0.orig.tar.gz

今回は現在実行中のバージョンを指定するために$(uname -r)を使いましたが、特定のカーネルパッケージにしたい場合はバージョンごとの文字列列に変更してください。

crashは本来--srcオプションでソースコードのディレクトリを指定できることになっています。これはバックエンドのgdbにdirectoryコマンドでソースコードディレクトリを指定するためのオプションです。しかしながら、Ubuntuのカーネルはソースツリーをフルパスで書いています。よって、--srcで指定するディレクトリ以下がフルパス相当になっていなくてはなりません。フルパスを取得する手っ取り早い方法は、crashでdisコマンドを打つことです。

crash> dis -s write_sysrq_trigger
FILE: /build/linux-HvkI5B/linux-5.11.0/drivers/tty/sysrq.c
LINE: 1151

dis: write_sysrq_trigger: source code is not available

コードが/build/linux-HvkI5B/linux-5.11.0以下であると記録されていることがわかります[2]⁠。

次のコマンドで上記のパスに合わせて、ツリーを移動してしまいます。

$ mkdir -p ~/Packages/linux/build/linux-HvkI5B/
$ mv linux-5.11.0 ~/Packages/linux/build/linux-HvkI5B/

これでソースコードの準備は整いました。カーネルのソースコードディレクトリはcrashコマンド起動時に--srcオプションを指定することで反映されます。

$ crash --src ~/Packages/linux/ \
  /usr/lib/debug/boot/vmlinux-5.11.0-22-generic /var/crash/202107040335/dump.202107040335
(略)

disコマンドに-sオプションを付けると、今度こそ指定したシンボルに該当するソースコードを表示してれます。

crash> dis -s write_sysrq_trigger
FILE: /build/linux-HvkI5B/linux-5.11.0/drivers/tty/sysrq.c
LINE: 1151

  1146  /*
  1147   * writing 'C' to /proc/sysrq-trigger is like sysrq-C
  1148   */
  1149  static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
  1150                                     size_t count, loff_t *ppos)
* 1151  {
  1152          if (count) {
  1153                  char c;
  1154
  1155                  if (get_user(c, buf))
  1156                          return -EFAULT;
  1157                  __handle_sysrq(c, false);
  1158          }
  1159
  1160          return count;
  1161  }

disコマンドの引数は、-sオプションを付けるとgdbの「list」の引数として解釈されます。よってアドレス指定も可能です。

クラッシュダンプの保存先をネットワーク上に変更する

前回はクラッシュダンプをローカルのファイルシステムに保存していました。しかしながらリモートで解析する予定がある、もしくは、ローカルには十分なサイズのストレージが存在しないのなら、クラッシュダンプを直接リモートに保存したいところです。Ubuntuのクラッシュダンプの設定は/etc/default/kdump-toolsにまとまっています。ここを変更すれば、SSH接続先のマシンやNFS上にクラッシュダンプを保存することが可能です。

設定方法自体は上記ファイルにコメントが記載されているため、そこまで迷うことはないでしょう。ここでは例として、SSH接続で保存する方法を紹介します。まず/etc/default/kdump-toolsの末尾のほうを次のように変更します。

# SSH - username and hostname of the remote server that will receive the dump
#       and dmesg files.
# SSH_KEY - Full path of the ssh private key to be used to login to the remote
#           server. use kdump-config propagate to send the public key to the
#           remote server
#SSH="<user at server>"
#SSH_KEY="<path>"
SSH="[email protected]"

最低限必要な設定は、SSH「ユーザー名@アドレス」を記載するだけです。上記はIPv4アドレスですが、もちろんホスト名等も可能です。SSH_KEYにはSSH接続する際の秘密鍵を指定します。何も指定しない場合は、/root/.ssh/kdump_id_rsaを自動生成してくれます。

設定ファイルの準備ができたら、一度SSHサーバー先にアクセスして公開鍵を登録します。これはkdump-config propagateコマンドで実現できます。

$ sudo kdump-config propagate
Need to generate a new ssh key...
The authenticity of host '192.168.0.59 (192.168.0.59)' can't be established.
ECDSA key fingerprint is SHA256:2GCRtJY7/m5ZAk/m1LB1EYO88iUPHF1NJ3+QpgVURmw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
[email protected]'s password:
propagated ssh key /root/.ssh/kdump_id_rsa to server [email protected]

これだけで準備完了です。あとはシステムをクラッシュさせてみましょう。クラッシュしたマシンの/var/crashではなく、接続先として設定したSSHサーバー上の/var/crash/以下に「⁠⁠クラッシュしたマシンのIPアドレス⁠⁠-⁠クラッシュ日時⁠⁠」なディレクトリが生成され、そこにクラッシュダンプが保存されているはずです。

前述のソースパッケージのダウンロード先に保存するようにしておけば、ターゲットマシンのストレージを消費することなく、詳細なデバッグが可能になります。

Ubuntu WikiのCrashdumpRecipeにはクラッシュダンプの解析に関する、いくつかのノウハウが掲載されています。カーネル関連の問題について、ケースごとの参考文献のリストもあるのでそちらも参考になるでしょう。単に不具合の出所を探りたいならカーネルのバージョンを切り替えつつ問題を絞り込む方法もあります。

カーネルのクラッシュは致命的な問題につながることが多々あります。カーネルクラッシュに遭遇したら、将来の自分のためにも、恐れず原因を追求するよう心がけましょう。

おすすめ記事

記事・ニュース一覧