crashコマンドではダンプファイルを解析するのに使用しますが、ダンプがなくても現時点のカーネルの状態をcrashのlive systemで確認することができます。
crashのlive systemではカレントプロセスのバックトレースを表示させることができませんが、今回はそれを無理矢理 表示させる方法を紹介します。
以下のコンフィグを有効にしたカーネルを作成して起動します。
Kernel hacking --->
Kernel debugging
このコンフィグを有効にするとデバッグ情報が入ったカーネル(vmlinux)が作成されます。このカーネルを/bootなどに置いておきます。今回の場合はvmlinux-2.6.15-testにしました。
このときのカーネルで再起動して以下のコマンドを実行します。
# crash /boot/vmlinux-2.6.15-test
crash 4.0-2.18.1 Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. Copyright (C) 2004, 2005, 2006 IBM Corporation ・・・・
KERNEL: /boot/vmlinux-2.6.15-test DUMPFILE: /dev/crash CPUS: 2 DATE: Sun Jun 10 14:14:13 2007 UPTIME: 00:10:09 LOAD AVERAGE: 0.08, 0.02, 0.01 TASKS: 89 NODENAME: hostname RELEASE: 2.6.15-test VERSION: #7 SMP Sun Jun 10 12:26:12 JST 2007 MACHINE: i686 (1862 Mhz) MEMORY: 1 GB PID: 2498 COMMAND: "crash" TASK: f7ddec90 [THREAD_INFO: e9670000] CPU: 0 STATE: TASK_RUNNING (ACTIVE) crash> |
crashのlive systemでは現時点のjiffiesの値などグローバルの変数などはすぐに確認できます。
以下はrdコマンドでjiffiesを表示させた例です。連続して見ると値が増えていきます。rdコマンドをメモリを直接表示させることができます。
crash> rd jiffies c03e9c00: 008a2637 7&.. crash> rd jiffies c03e9c00: 008a26e9 .&.. crash> rd jiffies c03e9c00: 008a2775 u'.. crash> |
今回はカレント(現時点で実行中)プロセスのバックトレースを見たいと思います。
ダンプでパニックしたときなどは最初に確認しますが、それをlive systemでもやってみます。
まずはcrashのpsコマンドでプロセスの確認です。
crash> ps PID PPID CPU TASK ST %MEM VSZ RSS COMM 0 0 0 c037f300 RU 0.0 0 0 [swapper] 0 1 1 f7ec1080 RU 0.0 0 0 [swapper] 1 0 1 f7ec15f0 IN 0.1 2012 696 init ・・・・ 2982 2980 0 f7dbc130 IN 0.2 7836 1724 sshd 2983 2982 0 f7cf08e0 IN 0.1 5484 1488 bash 3159 2957 0 f7c86760 IN 0.1 5712 1220 su 3160 3159 1 f725b5f0 IN 0.1 5488 1468 bash > 3175 2934 1 f7dbcc10 RU 6.0 68688 62172 crash ○ カレントプロセス > 3181 3175 0 f7322760 RU 0.1 4992 716 crash ○ カレントプロセス crash> |
一番左に">"が付いているのがカレントプロセスです。最初のcrashコマンドを実行したときの表示でもあるようにCPUが2つなのでcrashプロセス2つが同時に動いていますここで停止中のプロセスのバックトレースを見てみます。bt(バックトレース)コマンドでPIDを指定すれば見ることができます。
crash> bt 2982 PID: 2982 TASK: f7dbc130 CPU: 0 COMMAND: "sshd" #0 [dcdcfe3c] schedule at c030f4c3 #1 [dcdcfea4] schedule_timeout at c030fdff #2 [dcdcfecc] do_select at c0171b13 #3 [dcdcff38] core_sys_select at c0171dc2 #4 [dcdcff78] sys_select at c017239b #5 [dcdcffb8] sysenter_entry at c0103d6e EAX: 0000008e EBX: 0000000a ECX: 095633e0 EDX: 095633d0 DS: 007b ESI: 00000000 ES: 007b EDI: 00000000 SS: 007b ESP: bfaa6c50 EBP: bfaa6cb8 CS: 0073 EIP: 00ed6410 ERR: 0000008e EFLAGS: 00000246 |
sshデーモンを見てみましたが、selectシステムコールでスリープしているようです。
ここで現在実行中のプロセスcrashコマンドを見たいと思います。
crash> bt 3175 PID: 3175 TASK: f7dbcc10 CPU: 1 COMMAND: "crash" (active) crash> |
"(active)"の表示しか出力されません。crashではPIDを指定しなくてもbtコマンドではactive(カレントプロセス)だけを表示するオプションがあります。
このオプションで表示させてみます(他に解析時は"-t、-T、-l、-f"オプションも便利です)。
crash> help bt ・・・・ -a displays the stack traces of the active task on each CPU. (only applicable to crash dumps) ・・・・
crash> bt -a bt: -a option not supported on a live system crash> |
live systemでは実行中のカレントプロセスを表示できないようです。最初はこれで諦めていましたが、どうしても確認したいときがありました。以下は無理矢理 表示させる方法です。
crashではtaskコマンドでタスク(プロセス)を管理するtask_struct構造体を表示することができます。
まずはtask_struct構造体を見てみます。
crash> task 3175 PID: 3175 TASK: f7dbcc10 CPU: 1 COMMAND: "crash" struct task_struct { state = 0, thread_info = 0xde616000, usage = { counter = 8 }, flags = 8397056, ptrace = 0, lock_depth = -1, prio = 115, ・・・・・ crash> |
task_struct構造体にはスタックポインタもあります。hexコマンドは表示を16進数に変更します。
crash> hex output radix: 16 (hex) crash> task 3175 | grep esp esp0 = 0xde616ff8, esp = 0xde616e3c, saved_esp0 = 0x0, namespace = 0xf7ffdd00, crash> |
espをrdコマンドで見ます。
crash> rd 0xde616e3c 10 de616e3c: f72c7180 f71e8700 e2cad000 e4877000 .q,..........p.. de616e4c: 00000012 c14ab804 c0150173 00000000 ......J.s....... de616e5c: 80000000 e4876000 .....`.. |
これではわかりづらいので、"-s"オプションで表示させます。
crash> rd -s 0xde616e3c 120 de616e3c: f72c7180 f7364480 f4717000 f45f6000 de616e4c: 00000012 c14ab804 do_wp_page+0x343 00000000 de616e5c: 80000000 f45f5000 34717067 0838c67c de616e6c: dce94e10 c182ee48 c14ab804 dde33238 de616e7c: 00000008 00000000 1d8f4065 80000000 de616e8c: c149e620 34717067 80000000 c1504ae4 de616e9c: 1d8f4065 80000000 e01dfc60 __handle_mm_fault+0xa47 de616eac: e01dfc60 e4d07208 c1504ae4 1d8f4065 de616ebc: 80000000 00000000 contig_page_data+0x4a2c f7dbcc10 de616ecc: get_page_from_freelist+0x96 contig_page_data+0x4a28 0838c67c dce94e10 de616edc: f72c7180 00000000 00000000 00000000 de616eec: 00000000 1d8f4065 80000000 e4d07208 de616efc: b7c00000 00000001 edd11200 df7cdde0 de616f0c: 2605a386 466c2c56 current_fs_time+0x4a 00000001 de616f1c: f7f66600 df7cdde0 edd11220 00000009 de616f2c: 00000000 file_update_time+0x27 466c2c56 2605a386 de616f3c: df7cdde0 edd11220 pipe_writev+0x366 de616f7c de616f4c: 00000004 00000004 copy_to_user+0x36 0001e616 de616f5c: 00000000 c14bf370 crash_read+0xca bfa4b364 de616f6c: 1e616f6c 00000000 ea9d4240 crash_read de616f7c: bfa4b364 00000004 vfs_read+0x9f de616fa4 de616f8c: ea9d4240 fffffff7 00000008 de616000 de616f9c: sys_read+0x3c de616fa4 1e616fa4 00000000 de616fac: 00000000 00000004 08389060 sysenter_past_esp+0x56 de616fbc: 00000004 bfa4b364 00000004 08389060 de616fcc: 00000008 bfa4ac78 00000003 0000007b de616fdc: startup_32+0x7b 00000003 00698410 00000073 de616fec: 00000246 bfa4ac38 0000007b 00000000 de616ffc: 00000000 acpi_pci_root_driver 000000dc 000385e8 de61700c: 00000001 0000000b 00000000 00000000 |
詳細は調べていませんが他のプロセスとも比較して、task_structのesp0あたりまで表示させれば十分のようです。このようにするとlive systemでもカレントプロセスのバックトレースがなんとなくですが見ることができます。
live systemではまだまだおもしろいことができます。たとえばタイマ割り込みのハンドラでデータを見るためにprintk()を入れると表示が多すぎて起動できなくなってしまいます。
次回はwrコマンドでそのようなデータをprintk()で実際に表示させてみたりします。
コメント