次の手順でコンソールへのログ記録を有効にします。
$ dmesg --console-level 7
$ dmesg --console-on
次のようにシステムクラッシュが発生しました。
$echo c > /proc/sysrq-trigger
以下のように、Linuxコンソール(仮想コンソール)から競合スタックトレースを取得します。
[ 7.952685] sysrq: Trigger a crash
[ 7.952850] Kernel panic - not syncing: sysrq triggered crash
[ 7.953098] CPU: 0 PID: 71 Comm: linuxrc Not tainted 5.19.0-rc2 #1
[ 7.953259] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
[ 7.953655] Call Trace:
[ 7.954133] <TASK>
[ 7.954332] dump_stack_lvl+0x34/0x44
[ 7.954651] panic+0x102/0x27b
[ 7.954756] ? _printk+0x53/0x6a
[ 7.954847] sysrq_handle_crash+0x11/0x20
[ 7.954953] __handle_sysrq.cold+0x43/0x11b
[ 7.955065] write_sysrq_trigger+0x1f/0x30
[ 7.955167] proc_reg_write+0x4c/0x90
[ 7.955267] vfs_write+0xb4/0x290
[ 7.955362] ksys_write+0x5a/0xd0
[ 7.955453] do_syscall_64+0x3b/0x90
[ 7.955553] entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 7.955773] RIP: 0033:0x4a8531
[ 7.955999] Code: e0 ff ff ff f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f 80 00 00 00 00 8b 05 d2 26 1e 00 85 c0 75 16 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 57 c3 66 0f 1f 44 00 00 8
[ 7.956427] RSP: 002b:00007ffde8168508 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 7.956625] RAX: ffffffffffffffda RBX: 000000000101a8a0 RCX: 00000000004a8531
[ 7.956787] RDX: 0000000000000002 RSI: 00000000010201e0 RDI: 0000000000000001
[ 7.956949] RBP: 0000000000000001 R08: fefefefefefefeff R09: fefefefefefeff62
[ 7.957113] R10: 00000000000001b6 R11: 0000000000000246 R12: 00000000010201e0
[ 7.957275] R13: 0000000000000002 R14: 00007ffde8168701 R15: 00007ffde8168578
[ 7.957467] </TASK>
[ 7.957806] Kernel Offset: 0x34a00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[ 7.958215] ---[ end Kernel panic - not syncing: sysrq triggered crash ]---
そして、Linuxシステムがクラッシュしてキーボードがフリーズした場合、スタックトレースをどのようにコピーしますか?
しかし、カーネルパニックが発生した場合にスタックトレースを記録する他の方法はありますか? /etc/rsyslog.d/50-default.confで、次の方法でキャッシュを無効にしました(したがって常にディスクに書き込みます)。
*.*;auth,authpriv.none /var/log/syslog*
ただし、再起動後もクラッシュに関するログメッセージが見つかりません。
答え1
仮想マシンの場合、これは非常に簡単です。仮想マシンに別のシリアルコンソールを追加するだけです。たとえば、libvirtを使用すると、次のようになります。
<serial type='file'>
<source path='/var/lib/libvirt/consoles/vm-name.log'/>
<target type='isa-serial' port='1'>
<model name='isa-serial'/>
</target>
</serial>
また、VMの仮想ttyポートとシリアルポートをコンソールとして使用するようにVMのカーネルを設定する必要があります。たとえば、/etc/default/grubから:
GRUB_CMDLINE_LINUX="text console=tty0 console=ttyS1,115200n8"
コンソールに入るすべての内容はホストシステムのログファイルに保存されますが、VMを再起動するたびに上書きされます(追加されません)。もちろん、仮想マシンがシャットダウンしたときに/mv/cp/etcログファイルを循環させることもできます。
ところで、より多くのコンソールを設定できます。シリアルコンソールログインには、3番目のコンソール(別の仮想シリアルポートまたは物理パススルーシリアルポート)を使用できます。仮想マシンのシリアルポートでgettyを実行し、minicom
ホストマシン(またはヌルモデムケーブルを介して接続されているターミナル/ノートブック/その他のマシン)で実行するのと同じように、ターミナルプログラムを使用して接続する必要があります。パス) - パス)。
実際のマシンの場合ははるかに難しいです。近くに別のコンピュータがある場合(常にオンになっている場合)、実際のシリアルポートを使用し、そのコンピュータをヌルモデムケーブルで接続し、他のコンピュータにそのシリアルポートを通過するすべての内容を継続的に記録することができます。これはかなり一般的なカーネルデバッグ設定です(またはほぼすべての人が仮想マシンを使用し始める前の設定でした)。
もう一つの可能性は時々可能ですが信頼できない方法は、kern.*メッセージを別のコンピュータにリモートで記録するようにsyslogdを設定することです。これが特定の瞬間で動作するかどうかは、カーネルで正確に何がクラッシュするかによって異なります。ネットワークがまだ動作していて、いくつかのsyslog UDPパケットが出ている場合は問題ありません。リモートコンピュータで適切なシステムログファイルを確認してください。
これを行うために、いくつかのコンピュータでrsyslogを設定しました。特に、私のホームネットワーク上の2台のコンピュータはkali
(btw)Kali Linuxを実行せずにDebianを実行しています。 Kali Linuxが存在する前の90年代半ばからそうしてきました。ホスト名としてIndusを使用していました。もちろん、ハードウェアとOSはそれ以来何度もアップグレードされています)ganesh
(そしてDebianは)お互いにKernメッセージを送ります。
ガーネッシュは次のとおりです。
if $fromhost-ip == '127.0.0.1' and $syslogfacility-text == 'kern' then @kali
カリー:
if $fromhost-ip == '127.0.0.1' and $syslogfacility-text == 'kern' then @ganesh
答え2
stackoverflowで私の答えを見てください。 https://stackoverflow.com/a/72870750/10818184[方法decode_stacktrace.shを使用していますか? ][1]