<
Kernel 상에서 oops 메시지를
띄우고(강제 발생) 분석>
1. 수동 커널 트랩 추가
리눅스에서, 시스템 충돌을 디버깅하는 전통적인 방법은 Oops 메시지의 상세를 분석하는 것이었다. 상세를 포착하면 메시지는 ksymoops 유틸리티로 전달된다. 이것은 코드를 명령어로 변환하고 스택 값을 커널 심볼로 변환한다. 많은 경우에, 오류의 원인을 파악할 수 있는 충분한 정보가 된다. Oops 메시지에는 코어 파일이 포함되어 있지 않다.
Oops 메시지: 기본적으로 커널이 심각한 문제를 직면했을 때, 커널이 생성한 정보이다.
` NULL 포인터 역참조나 벗어난 메모리 영역 참조와 같은 버그와 관련된 코드
A. 수동 커널 트랩 추가 과정
* Version: Kernel 2.6.29.3 원시 코드를 사용 (경로: /usr/src/ 폴더에 저장)
$ vi /usr/src/linux-2.6.29.3/kernel/sysct1.c
// kern_table 배열에 추가 내용
{
.ctl_name = KERN_TRAP_KERNEL,
.procname = "trap_kernel",
.data = &trap_kernel_value,
.maxlen = sizeof (int),
.mode = 0644,
.proc_handler = &proc_dointvec_trap_kernel,
},
$ vi /usr/src/linux-2.6.29.3/kernel/sysct1.c
// 파일 수정 추가
EXPORT_SYMBOL (proc_dointvec_trap_kernel);
$ vi /usr/src/linux-2.6.29.3/include/linux/sysctl.h
//헤더 파일에 선언 추가
KERN_TRAP_KERNEL = 77;
$ vi /usr/src/linux-2.6.2/kernel/sysct1.c
// “proc_dointvec_trap_kernel기존에 사용하는 proc_dointvec를 수정한 처리기” 추가
2. 커널 Oops 메시지 분석
A. oops 기본 자료
/usr/src/linux-2.6.29.3/Documentation
B. oops 출력
- 커널에 대한 오류 발생시, oops를 보낸다.
→ 커널은 비정상적(inconsistent)인 상태
#oops가 발생하고
나면 커널은 더 이상 진행하지 못하고 패닉(panic)상태가 됨
#시스템 즉시
정지
idle 태스크 (pid 0번) , init 태스크 (pid 1번)
– 패닉상태, 더 이상 진행 못함
그 밖의 다른 프로세스에서 oops발생하면
커널은 프로세스 종료, 계속 일 진행
- 콘솔에 오류 메시지 출력
- 레지스터의 내용을 덤프
- 백트레이스(back trace)를 제공하는 것과 관련
C. oops 출력 결과
$ echo 1 > /proc/sys/kernel/trap_kernel
// write 플래그가 1로 설정
$ echo 0 > /proc/sys/kernel/trap_kernel
// write 플래그가 0으로 설정
$ cat /proc/sys/kernel/trap_kernel
// 현재 write 플래스 표시
$ echo 3 > /proc/sys/kernel/trap_kernel
그림 4 write 플래그 설정 화면
$ vi /var/log/messages
그림 5 /var/log/messages 결과 화면
$ vi /var/log/messages
// 출력 결과 확인
그림 6 echo 9 /var/log/messages 결과 화면
D. oops 출력 결과 분석
I. Oops: 0002 [#3] SMP - 분석
① 페이지 결함 오류 코드 (page fault error code)를 나타내는 16진수
② 0002 = 0010(16)
0: 결함이 명령어
패치 단계에서 일어나지 않음
0: 커널 모드
1: 쓰기
0: 페이지 발견 못함
표 1페이지 결함 오류 코드
|
값 |
|
비트 |
0 |
1 |
0 |
페이지 발견 못함 |
보호 결함 |
1 |
읽기 |
쓰기 |
2 |
커널 모드 |
사용자 모드 |
3 |
결함이 명령어 단계에서 일어나지 않음 |
결함이 명령어 패치 단계에서 일어남 |
③ [#3]: 마지막 재시동 이후부터 발생한 oops 숫자를
추적하는 사망 카운터 (die counter)
II. Pid: 2930, comm: bash
Trained: GD(2.6.29.3 #4) System Product Name분석
① Pid: 2930
pid 는 문제를 일으킨 사용자 영역 프로세스 ID를 알려줌
② comm.: bash Trained
comm: 은 프로세스 이름이 bash 라는 것을 알려줌
trained:
III. EIP: 0060: [<c043bf31>]
EFLAGS: 00210246 CPU: 0 – 분석
① EIP: 32비트 x86 시스템에서 사용하는 명령 포인터
② RIP: AMD64 에서 사용하는 명령 포인터
③ “0060”: CS 레지스터의 내용
IV. EIP is at
proc_dointvec_trap_kerenl+0x35/0x7d – 분석
① proc_dointvec_trap_kerenl+0x35/0x7d
: 커널이 EIP 주소를 사람이 이해하기 쉬운 형식으로 변환 결과
V. Process bash (pid: 2680, ti=f5904000
task=f3050000 task.ti=f5904000)– 분석
① “Process bash (pid: 2680 “
3. 기타
A. 실습 시 문제 해결
* 오류 해결:
scripts/kconfig/mconf.c:91: error: static declaration of? ’current_menu’??follows non-static declaration
→ $ vi /usr/src/linux-2.6.2/scripts/kconfig/mconf.c
// static struct menu *current_menu; 부분에 static 을 없애줌
헤더파일 선언
extern int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user * oldlenp, void __usr * newval, size_t newlen)
< 컴파일 순서 >
$ make mrproper
$ make menuconfig
$ make
$ make modules
$ make modules_install
$ make install
zImage 2.6.29.3 으로 실행.
'Education > Linux Kernel' 카테고리의 다른 글
vmware 키보드 먹통 (2) | 2010.07.07 |
---|---|
인터럽트 (0) | 2010.02.05 |
vim 설정 (0) | 2009.11.18 |
커널 소스 트리 (0) | 2009.11.18 |
root passwd (0) | 2009.10.28 |