150804_kernel_debug. [75] DATE

Download Report

Transcript 150804_kernel_debug. [75] DATE

18장. 디버깅
리눅스 커널 심층 분
석
August 4th. 2015
Cho, Hyojae
Index
①배경지식 (클라우드 컴퓨팅)
②서론
③오픈스택 구성요소들의 기능
④오픈스택 서버 구축
⑤오픈스택 네트워크 구성
⑥멀티-테넌시 네트워크
⑦결론
2
커널 디버깅
커널 개발의 어려운 점 : Debug
• 시스템이 망가질 위험성 ↑
• 수많은 이유로 버그 발생
• 버그가 드러나는 모습이 다양함
• 여러 사건의 연쇄적 발생의 결과
→ 버그를 안정적으로 재현해야 함
3
준비 사항
버그 해결을 위한 준비 사항
•
•
•
•
•
잘 정의된 구체적인 버그
안정적으로 재현 가능해야 함
버그가 존재하는 커널 버전
관련 코드에 대한 지식
행운
4
출력을 이용한 디버깅
printk()
• 커널 출력 함수
• C라이브러리의 printf()와 거의 동일한 사용법
• 커널의 어느 곳에서나 호출 가능
(인터럽트 컨텍스트 및 프로세스 컨텍스트)
Lock을 사용하고 있는 상황
5
출력을 이용한 디버깅
로그수준
• 로그수준에 따른 메시지의 콘솔 출력 여부 결정
• 특정 값 이하의 로그수준에 해당하는 메시지 출력
예시
printk(KERN_WARNING “이것은 경고!”\n);
printk(KERN_DEBUG “이것은 디버그 알림!”\n);
printk(“로그 수준을 지정하지 않았음!”\n);
printk(“<4>이것은 경고!”\n);
printk(“<7>이것은 디버그 알림!”\n);
printk(“<4>로그 수준을 지정하지 않았음!”\n);
6
출력을 이용한 디버깅
사용 가능한 로그수준
• <linux/kernel.h>에 정의됨
로그 수준
설명
KERN_EMERG
비상 상황. 시스템이 중단될 수도 있음
KERN_ALERT
즉시 주의를 기울여야 할 문제
KERN_CRIT
치명적인 상황
KERN_ERR
오류
KERN_WARNING
경고
KERN_NOTICE
일반적이지만, 주의가 필요한 상황
KERN_INFO
정보 제공을 위한 메시지
KERN_DEBUG
디버그 메시지. 보통은 불필요함
7
출력을 이용한 디버깅
로그 버퍼
• LOG_BUF_LEN 크기의 원형 버퍼에 저장
• 커널 컴파일 시 CONFIG_LOG_BUF_SHIFT 옵션
• 기본값 : 16KB (단일 프로세서 시스템)
8
출력을 이용한 디버깅
syslogd와 klogd
• 로그 파일 기록 : user-space의 klogd 데몬
- 로그 버퍼를 읽은 후 syslogd 데몬을 거쳐
시스템 로그 파일에 기록.
• 로그 버퍼를 읽는 방법
- /proc/kmsg 파일 읽기 (기본값)
- syslog() 시스템 호출
• 로그 파일의 저장 위치
- 기본값
- 설정 변경
: /var/log/messages
: /etc/syslog.conf
• 콘솔 로그 수준 변경 : klogd -c
9
웁스
웁스(oops)
• 커널은 시스템의 관리자
- 프로세스 종료 또는 스스로 문제를 수정할 수 없음
• 커널이 사용자에게 무언가 나쁜 일이 일어났다는
사실을 알려주는 일반적인 방법
웁스 발생 과정
• 콘솔 오류 메시지 출력
• 레지스터 내용물, 역추적 정보 제공 등
10
웁스
웁스 발생 이유
• 메모리 접근 위반
• 유효하지 않은 명령 사용 등
커널 패닉이 발생하는 웁스의 예
• 인터럽트 컨텍스트
• idle 태스크(pid 0), init 태스크(pid 1)
이외의 프로세스에서 웁스 발생 시 해당 프로세스 종료 후
실행 계속 시도
11
웁스
웁스 예제
• ksymoops saved_oops.txt
Oops: Exception in kernel mode, sig: 4
Unable to handle kernel NULL pointer dereference at virtual address 00000001
NIP: C013A7F0 LR: C013A7F0 SP: C0685E00 REGS: c0905d10 TRAP: 0700
Not tainted
MSR: 00089037 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
TASK = c0712530[0] 'swapper' Last syscall: 120
GPR00: C013A7C0 C0295E00 C0231530 0000002F 00000001 C0380CB8 C0291B80 C02D0000
GPR08: 000012A0 00000000 00000000 C0292AA0 4020A088 00000000 00000000 00000000
GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
GPR24: 00000000 00000005 00000000 00001032 C3F7C000 00000032 FFFFFFFF C3F7C1C0
Call trace:
[c013ab30] tulip_timer+0x128/0x1c4
[c0020744] run_timer_softirq+0x10c/0x164
[c001b864] do_softirq+0x88/0x104
[c0007e80] timer_interrupt+0x284/0x298
[c00033c4] ret_from_except+0x0/0x34
[c0007b84] default_idle+0x20/0x60
[c0007bf8] cpu_idle+0x34/0x38
[c0003ae8] rest_init+0x24/0x34
12
커널 디버깅 옵션
유용한 옵션
• spinlock 소유 상태에서 휴면 상태를 들어가는지
확인
• lock을 소유한 채로 휴면 상태 → Deadlock
CONFIG_PREEMPT=y
CONFIG_DEBUG_KERNEL=y
CONFIG_KALLSYMS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
13
버그 확인과 정보 추출
BUG() 와 BUG_ON() 함수
• 함수 호출시 인위적 oops 발생
- 아키텍처에 따라 oops 발생 방법이 다름
- 일반적으로, 잘못된 명령어 사용
if(bad_thing)
BUG();
BUG_ON(bad_thing);
14
버그 확인과 정보 추출
panic() 함수
• BUG()함수보다 더 치명적인 오류
• 호출시 오류 메시지 출력 후 커널 중지
• 최악의 상황에서만 사용
if(terrible_thing)
panic(“terrible_thing is %ld\n”, terrible_thing);
15
버그 확인과 정보 추출
dump_stack() 함수
• 스택 역추적 정보만을 콘솔에 표시하고 싶을 때.
• 레지스터의 내용물과 함수 역추적 정보를 콘솔에 출력
if(!debug_check)
printk(KERN_DEBUG “provide some information..\n”);
dump_stack();
16
만능 SysRq 키
SysRq
• 진행중인 작업과 상관 없이 커널과 통신
• 활성화 방법
- CONFIG_MAGIC_SYSRQ 설정 옵션을 통해 활성화
- sysctl을 이용하여 활성화
echo 1> /proc/sys/kernel/sysrq
17
만능 SysRq 키
로그 수준
설명
SysRq-b
시스템을 다시 시작한다
SysRq-e
init을 제외한 모든 프로세스에 SIGTERM 시그널을 보낸다.
SysRq-h
콘솔에 SysRq 도움말을 출력한다
SysRq-i
init을 제외한 모든 프로세스에 SIGKILL 시그널을 보낸다
SysRq-k
안전 접근 키 : 현 콘솔의 모든 프로그램을 종료한다.
SysRq-l
init을 포함한 모든 프로세스에 SIGKILL 시그널을 보낸다.
SysRq-m
메모리 정보를 콘솔에 출력한다.
SysRq-o
시스템을 종료한다.
SysRq-p
레지스터 정보를 콘솔에 출력한다.
SysRq-r
키보드의 raw 모드를 끈다.
SysRq-s
마운트된 모든 파일 시스템의 변경 사항을 디스크에 저장한다.
SysRq-t
태스크 정보를 콘솔에 출력한다.
SysRq-u
마운트된 모든 파일 시스템의 마운트를 해제한다.
18
gdb & kgdb
커널에 gdb 사용하기
• gdb 실행
gdb vmlinux /proc/kcore
• 특정 변수의 값 출력
p global_variable
• 함수 디스어셈블
disassemble function
→ gdb를 이용해서는 커널의 데이터 변경 불가.
19
gdb & kgdb
kgdb
• 시리얼 연결을 통해 원격에서 커널 디버깅
• 두 대의 컴퓨터 필요
- 첫 번째 컴퓨터는 kgdb 패치가 된 커널을 실행
- 두 번째 컴퓨터는 시리얼 연결을 통해 gdb로 첫 번째
컴퓨터 디버깅
• gdb의 전체 기능을 사용할 수 있음.
-
모든 변수의 읽기, 쓰기
중단지점 설정
감시지점 설정
단계별 실행
20
GIT를 사용한 이진 탐색
• git 이진 탐색 명령 실행
git bisect start
• 문제가 있는 것으로 알려진 가장 오래된 리비전 지정
git bisect bad <revision>
• 정상 동작하는 것으로 알려진 리비전 지정
git bisect good v2.6.28
• 버그 확인 후 정상 동작시
git bisect good
• 버그 발생 시
git bisect bad
21
결론
커널 디버깅 기법
• 커널에 내장된 디버깅 지원체계 및 디버거
• 로그 활용법
• git을 사용한 이진 탐색
22