Linux 커널 시스템 충돌 시 커널 로그 메시지를 기록(복사)하는 방법

Linux 커널 시스템 충돌 시 커널 로그 메시지를 기록(복사)하는 방법

다음을 통해 콘솔에 로깅을 활성화합니다.

$ 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 로그 파일을 순환할 수 있습니다.

그런데 더 많은 콘솔을 구성할 수 있습니다. 직렬 콘솔 로그인을 위해 세 번째 콘솔(다른 가상 직렬 포트 또는 실제 통과 직렬 포트)을 사용할 수 있습니다. 가상 머신의 직렬 포트에서 getty를 실행하고 minicom호스트 머신(또는 널 모뎀 케이블을 통해 연결된 터미널/노트북/기타 머신)에서 실행하는 것처럼 터미널 프로그램을 사용하여 연결해야 합니다. 통과)-통과)..

실제 머신의 경우에는 훨씬 더 어렵습니다. 근처에 다른 컴퓨터가 있는 경우(항상 켜져 있는 경우) 실제 직렬 포트를 사용하고 해당 컴퓨터를 널 모뎀 케이블로 연결한 다음 다른 컴퓨터에서 해당 직렬 포트를 통과하는 모든 내용을 지속적으로 기록하도록 할 수 있습니다. 이는 상당히 일반적인 커널 디버깅 설정입니다(또는 거의 모든 사람이 가상 머신을 사용하기 시작하기 전의 설정이었습니다).

또 다른 가능성은때때로가능하지만 신뢰할 수 없는 방법은 kern.* 메시지를 다른 컴퓨터에 원격으로 기록하도록 syslogd를 구성하는 것입니다. 이것이 특정 순간에 작동하는지 여부는 커널에서 정확히 무엇이 충돌하는지에 따라 다릅니다. 네트워크가 여전히 작동 중이고 일부 syslog UDP 패킷이 나가고 있다면 괜찮습니다. 원격 컴퓨터에서 해당 시스템 로그 파일을 확인하세요.

이 작업을 수행하기 위해 일부 컴퓨터에 rsyslog를 구성했습니다. 특히 내 홈 네트워크에 있는 두 대의 컴퓨터는 kali(btw) Kali Linux를 실행하지 않고 Debian을 실행하고 있습니다. Kali Linux가 존재하기 오래 전인 90년대 중반부터 그렇게 해왔습니다. 호스트 이름으로 Indus를 사용하고 있었습니다. 물론 하드웨어와 OS는 그 이후로 여러 번 업그레이드되었으며) ganesh(그리고 데비안은) 서로에게 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]

관련 정보