커널 크래시 분석을 잘하는 게 왜 중요할까요? 너무 당연한 질문인가요? 사실 세상에 너무 당연한 질문은 없습니다. 어쩌면 너무 당연한 질문에 답하려고 고민하다가 많은 걸 깨닫는 경우가 많은 것 같습니다.
 
여러분이 리눅스 드라이버를 개발하거나 새로운 리눅스 커널 버전을 포팅했다고 가정하겠습니다. 그런데 안타깝게도 부팅 도중 아래와 같은 로그를 출력하는 커널 크래시가 100% 발생하고 있습니다. 어떻게 분석해야 할지 몰라 하루 꼬박 밤을 새웠습니다. 참 이럴 때 난감하죠. 
[ 0.986578] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 0.986589] CPU: 0 PID: 1 Comm: swapper Not tainted 3.18.20 #1
[ 0.986610] [<c0013260>] (unwind_backtrace) from [<c0011440>] (show_stack+0x10/0x14)
[ 0.986624] [<c0011440>] (show_stack) from [<c05a68b4>] (panic+0xf0/0x2dc)
[ 0.986640] [<c05a68b4>] (panic) from [<c083c164>] (mount_block_root+0x26c/0x2b0)
[ 0.986655] [<c083c164>] (mount_block_root) from [<c083c37c>] (prepare_namespace+0x88/0x1ac)
[ 0.986668] [<c083c37c>] (prepare_namespace) from [<c083bdac>] (kernel_init_freeable+0x16c/0x1b0)
[ 0.986681] [<c083bdac>] (kernel_init_freeable) from [<c05a5d6c>] (kernel_init+0x8/0xe0)
[ 0.986693] [<c05a5d6c>] (kernel_init) from [<c000dda0>] (ret_from_fork+0x14/0x34)
[ 1.982696] Rebooting in 5 seconds..
 
그런데 어떤 동료가 산신령 같이 나타나서 같이 분석을 시작합니다. 이것은 rootfs 파일 시스템 마운트를 못해서 발생한 문제라고 하네요. 그리고 꼼꼼히 로그를 같이 보면서 파티션 마운트가 제대로 됐는지 부트 디바이스가 제대로 동작하는지 점검 후 문제가 해결됐습니다. 그러면 여러분 기분은 어떨까요? (아 조금 어려운 용어 “파티션 마운트”, “부트 디바이스”, “rootfs”가 보이죠? 이번 장 마지막에 친절히 설명했으니 참고하세요.)
 
그 동료에게 참 고맙게 생각하겠죠. 흠, 그런데 전 약간 다릅니다. 물론 이 동료에게 감사 표현을 할 것이 분명하죠. 이런 문제를 해결 못한 저를 엄청 자책할 겁니다. 앞으로 비슷한 커널 크래시가 나오면 바로 해결할 수 있도록 열심히 준비하면서 말이죠. 
 
 
일단 이 동료는 커널 크래시 문제를 해결했습니다. 다시 반복하자면 어떤 문제를 해결했죠. 임베디드 리눅스 개발자에게 문제 해결 능력은 가장 중요한 실무 역량입니다. 모든 회사가 애타게 찾는 개발자는 문제 해결 능력이 있는 개발자입니다. 문제 해결 능력이 있는 개발자를 당연히 실력 있다고 봐야 겠죠. 그런데 문제 해결을 하기 위한 첫걸음은 문제를 정확히 분석하는 능력입니다. 대부분 로그를 분석하는 과정에 답이 있는 경우가 많거든요. 실력 있는 개발자가 되기 위해서 커널 크래시 분석 능력이 키우는 게 중요합니다. 
 
리눅스 커뮤니티
그런데 가끔 바로 문제 해결을 못 할 때도 있습니다. 예를 들어 리눅스 버전을 새롭게 업그레이드했는데 커널 크래시가 발생할 경우죠. 콜스택 모두 우리 눈에 낯선 함수입니다. 이 경우 어떻게 해야 할까요? 
 
이럴 때 너무 자신을 자책하지 마세요. 리눅스 커널은 수 많은 서브 시스템으로 이루어져 있어 소스를 볼 수 있는 범위가 넓습니다. 그래서 모든 커널 코드를 잘 알기 힘듭니다. 그래서 리눅스 커널에는 분야별로 전문적으로 코드 리뷰를 하는 메인테이너가 있습니다. 우선 아래와 같은 정보를 포함해서 정밀히 분석해야 합니다. 
- 크래시가 발생한 정확한 코드 위치와 그 이유 
- 프로세스 이름 
- 인터럽트 컨택스트 여부 
- ftrace log 상세 분석 
 
이렇게 정밀하게 분석을 한 다음 리눅스 커뮤니티에 업로드를 하면 되죠. 리눅스 커널 메일링 리스트에 공유하면 좋습니다. 리눅스 커널은 강력한 커뮤니티가 큰 강점이라고 알려져 있죠. 그런데, 커널 로그만 복사해서 버그를 알리면 제대로 도움을 받을 수 있을까요? 프로세스 이름, 정확히 크래시가 난 코드와 함수 위치, 문제가 발생한 재현 경로를 자세히 올려야 도움을 받을 가능성이 높습니다. 그래서 커널 크래시 분석 능력이 중요합니다. 
 
효율적인 업무 진행
가끔 주말 동안 스트레스 테스트를 디바이스에 돌릴 경우가 있습니다. 안드로이드에서 몽키 테스트라고 하죠. 실제 유저가 디바이스를 사용하듯이 테스트 시나리오를 만들어 신뢰성 테스트를 하는 것입니다. 그런데 보드 20대 중에 10대가 커널 크래시를 맞으면 이 때 어떤 방식으로 일을 하는 게 효율적일까요? 10개의 코어 덤프를 리눅스 커널 커뮤니티나 벅질라 이슈에 올려야 할까요? 10개의 코어 덤프를 올리는 일도 보통 오래 시간이 걸리는 일이 아니죠. 10개의 코어 덤프를 크래시 유틸리티로 자세히 분석하면 커널 크래시의 원인은 2~3개로 좁혀지는 경우가 많습니다.
 
커널 크래시가 발생하는 패턴을 생각해 볼 필요가 있습니다. 우리는 보통 문제가 발생한 코드에서 바로 커널 크래시가 발생할 것이라 예상할 때가 있어요. 정말 문제 코드에서 딱 크래시가 발생하면 얼마나 좋을까요? 사실 그렇지 않습니다. 원인은 하나 인데 다양한 로그로 커널 크래시가 발생할 수 있습니다. 가장 대표적인 예가 슬랩 메모리를 누군가 깨 먹는 경우입니다. 아니면 특정 디바이스에서만 커널 크래시가 발생하는 경우도 있습니다. 갑자기 다양한 커널 로그로 랜덤하게 크래시가 발생하면 정말 죽을 맛이죠. 이럴 때 정밀하게 커널 크래시 디버깅을 하면 그 범인을 잡을 수 있습니다.
 
프로젝트 마감에 큰 걸림돌
프로젝트 마감이 내일인데 커널 크래시가 발생하면 여러분들은 기분은 어떨까요? 제품 출시에 걸림돌이 되는 가장 큰 이슈는 커널 크래시입니다. 사소한 버그는 첫 제품 출시 후 잡자고 고객사를 설득할 수 있습니다. 그런데 커널 크래시를 고객사에게 출시 후에 잡겠다고 협의를 할 수 있을까요? 실현 불가능한 현실이죠. 이렇게 프로젝트 막바지에 가끔 임베디드 리눅스 개발자들은 이 문제를 해결하기 전에 집에 못 가는 짜증나는 경험이 생각 날 겁니다.
 
저 같은 경우엔 예전에 어느 매니저님께서 담요와 베개를 갖고 제 옆에 오셨던 악몽이 되살아 나는군요. 이렇게 말씀하시면서요. “이 문제 해결하기 전까지 집에 못가.” 물론 그 당시 열심히 크래시 디버깅을 해서 문제의 원인을 잡아 집에 들어는 갔습니다.
 
커널 크래시 디버깅을 통한 학습
커널 디버깅을 하면 할수록 리눅스 커널과 디바이스 실력이 빨리 향상됩니다. 커널 크래시 디버깅을 잘하면 리눅스 커널 개발 능력이 업그레이드 되기 때문입니다. 리눅스 커뮤니티나 주위 고수들 중에 커널 크래시 디버깅을 잘 못하는 개발자를 본 적이 없습니다.
 
가끔은 커널 크래시 디버깅을 잘하는 개발자를 폄하하는 분도 만난 적이 있습니다. “커널 디버깅 툴(crash utility, Trace32, ftrace)을 잘 쓸 뿐이다.”라고 말이죠. 맞습니다. 리눅스 커널 고수들 정말 디버깅 툴 잘 씁니다. 그런데 리눅스 커널에 대한 깊은 이해와 커널 자료구조에 익숙하지 않고 절대 커널 크래시 디버깅을 능숙하게 할 수 없습니다.
 
#커널 크래시 디버깅 및 TroubleShooting
 
 
 
# Reference: For more information on 'Linux Kernel';
 
디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1
 
디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2
 
 

+ Recent posts