crash 는 리눅스 커널 소스를 GNU gdb 와 연동하여 디버깅할 수 있는 도구다. gdb 는 다양한 기능을 제공하지만 커널 덤프 파일을 분석하기에는 불편하다. crash 는 이러한 덤프 파일을 분석하는데 도움이 되는 다양한 기능을 제공한다.
crash 설치하기 crash 는 아래의 명령어를 통해 설치가 가능하다:
sudo apt install linux-crashdump
이제 crash -v 를 입력해서 버전을 확인한다. 만일 버전이 7.3 이하라면 5.12.2 커널에서는 제대로 동작하지 않을 수 있다. 만일 버전이 낮다면 공식 레포지토리에 들어가서 설치하는 방법으로 진행해야 한다.
git clone "https"//github.com/crash-utility/crash" cd crash make sudo cp -v crash /bin/crash
위 명령어를 순서대로 입력한 후 다시 crash -v 를 입력해서 버전을 확인한다. 아래와 같이 나오면 성공이다.

또한 crash 를 사용하기 위해서는 커널 소스를 -g 옵션으로 컴파일해야 하는데 일반적으로 다 설정이 되어 있으므로 특별히 무언가 건드릴 필요는 없다. 혹시 궁금하다면 커널을 빌드할 때 사용했던 .config 파일에서 다음의 정보를 확인하길 바란다.
CONFIG_DEBUG_INFO=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_FRAME_POINTER=y
crash 실행 with Live System 아무 옵션도 주지 말고 crash 입력해서 실행해봐라.

다음과 같은 메세지가 나올텐데, 보는 것처럼 crash 프로그램은 /dev/mem 디바이스 노드에 접근한다. 따라서 root 권한으로 실행하지 않으면 프로그램이 제대로 실행되지 않을 수 있다. root 권한으로 다시 crash 를 실행하면 아래와 같이 터미널의 입력부가 crash> 로 바뀌게 된다:

위와 같이 나오면 성공이다. 만일 이렇게 실행이 안된다면 .config 파일의 CONFIG_STRICT_DEVMEM 값을 제거하고 다시 빌드, /etc/default/grub 파일의 GRUB_CMDLINE_LINUX 의 값을 아래와 같이 바꾸길 바란다:
GRUB_CMDLINE_LINUX="crashkernel=auto console=ttyS0 console=tty0 panic=5 net.ifnames=0 biosdevname=0"
crash 실행 with dump file crash 는 /dev/mem 에 실시간으로 접근하여 커널을 디버깅할 수도 있지만, 커널 실행 데이터를 미리 덤프하여 디버깅하는 것도 가능하다. 커널 데이터 덤프를 위해서는 아래의 도구를 설치해야 한다:
sudo apt install kexec-tools sudo apt install linux-crashdump sudo apt install kdump-tools
필자는 이미 모두 설치되어 있었는데 만일 설치가 안되어 있다면 설치하도록 하자. 이제 커널 덤프를 가능하도록 만들기 위해 다음과 같이 실행하여 "Yes" 를 선택한다.
sudo dpkg-reconfigure kdump-tools
위에서 YES 를 선택하면 /etc/default/kdump-tools 환경설정 파일의 값이 USE_KDUMP=1 로 바뀔 것이다.
sudo kdump-config show
를 입력해서 결과를 확인할 수도 있다. 필자는 아래와 같은 결과가 나왔다.

마지막으로 /etc/default/kexec 파일의 내용이 아래와 같이 설정되어 있는지 확인한다:
# Defaults for kexec initscript
# sourced by /etc/init.d/kexec and /etc/init.d/kexec-load
# Load a kexec kernel (true/false)
LOAD_KEXEC=true
# Kernel and initrd image
KERNEL_IMAGE="/vmlinuz"
INITRD="/initrd.img"
# If empty, use current /proc/cmdline
APPEND=""
# Load the default kernel from grub config (true/false)
USE_GRUB_CONFIG=true
반드시 LOAD_KEXEC 과 USE_GRUB_CONFIG 가 true 로 설정되어 있어야 한다. 이제 아래의 명령어를 입력해서 커널을 덤프한다. 덤프 명령어를 입력하면 시스템은 자동으로 재부팅된다.
su
echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger
crash 명령어 사용하기사용 가능한 crash 명령어는 crash 프로그램이 실행된 상태로 help 를 입력해서 확인할 수 있다.

backtrace 명령 (bt) backtrace 명령은 커널 안에서 명령들이 실행된 흐름을 추적할 수 있다. 여러가지 인자를 전달할 수 있지만 필자는 간단히 bt 명령만 입력해서 실행시켜 보았다. 자세한 내용은 help bt 를 입력해서 확인하길 바란다.

bt 명령어만 실행하면 다음과 같이 현재 실행된 프로세스의 정보를 출력한다.
ps 명령어ps 명령어는 프로세스의 상태 정보를 표시한다. ps -k 옵션으로 실행하면 커널 프로세스(태스크, 쓰레드) 리스트가, ps -u 옵션으로 실행하면 유저 프로세스 리스트가 출력된다.

위 정보는 커널 프로세스 리스트 정보이고 아래는 유저 프로세스 리스트이다:

struct 명령 struct 명령은 커널 구조체들의 구조와 그 안의 값들을 출력한다. 커널 스케쥴러에서 중요한 역할을 하는 task_struct 구조체는 아래와 같이 출력된다.
crash > strut task_struct

내용이 너무 길어서 아주 일부만 잘라서 가져왔는데 직접 출력해서 그 내용을 확인해보길 바란다. -o 옵션을 추가하면 구조체의 멤버 변수들의 오프셋도 같이 출력되니 옵션을 주고 출력하는 것도 좋을 것이다.
task 명령 task 명령은 task_struct 구조체와 thread_info 구조체 안의 내용을 출력한다.

위 삽화는 아무런 옵션없이 그냥 명령을 입력했을 때의 출력결과이다. task 명령만 입력하게 되면 실행되고 있는 프로세스의 정보를 출력하게 된다. 프로세스 명은 "crash" 이고 프로세스 ID 는 23540 이다.
vm 명령 vm 명령은 커널의 가상 메모리 정보를 출력한다. -m <pid> 형태로 옵션을 주면 해당 프로세스의 mm_struct 구조체의 내용을 출력한다. 아래의 삽화는 현재 실행 중인 crash 프로그램의 mm_struct 의 일부분이다:

kmem 명령 kmem 명령은 커널 메모리와 관련된 내용들을 보여준다. -i 옵션을 주고 명령을 실행하면 현재 메모리 사용 정보를 출력한다:

sym 명령sym 명령은 커널의 심볼 정보를 출력한다. -l 옵션으로 전체 심볼의 정보를 출력한 결과는 아래와 같다:

p 명령p 명령은 pinrt 의 약자이다. 심볼이나 표현식의 값을 출력한다.
list, tree 명령list, tree 명령은 커널의 연결 리스트와 트리 자료구조의 정보를 출력한다.
foreach 명령은 여러가지 명령이 반복 실행된 결과 데이터를 출력한다.
[사이트] https://github.com/crash-utility/crash
[책] 리눅스 커널 소스 해설: 기초입문 (정재준 저)