Linux Kernel을 디버깅하거나 Kernel Panic, Oops 로그를 분석하다 보면 System.map, kallsyms, Symbol, Symbol Table과 같은 용어를 자주 접하게 됩니다.
예를 들어 Kernel Panic 로그에 다음과 같은 내용이 출력될 수 있습니다.
RIP: 0010:do_page_fault+0x124/0x320
이 메시지만 보면 주소와 함수 이름만 알 수 있을 뿐 정확한 코드 위치는 알기 어렵습니다.
이때 Kernel Symbol을 활용하면 메모리 주소를 실제 함수나 변수 이름으로 변환하여 문제를 훨씬 쉽게 분석할 수 있습니다.
이번 글에서는 Linux Kernel Symbol의 개념부터 System.map, /proc/kallsyms, 심볼 테이블의 구조와 활용 방법까지 자세히 알아보겠습니다.
Linux Kernel Symbol이란?
Kernel Symbol은 커널 내부 함수와 전역 변수에 부여된 이름(Name)과 메모리 주소(Address)의 대응 정보입니다.
구조는 다음과 같습니다.
Function Name
↓
Memory Address
↓
Kernel Symbol
즉, 메모리 주소를 사람이 이해할 수 있는 이름으로 연결해 주는 역할을 합니다.
Symbol이 필요한 이유
CPU는 주소만 이해합니다.
예를 들어
0xffffffff81234567
이라는 주소만 출력된다면 사람이 어떤 함수인지 알기 어렵습니다.
하지만 Symbol을 사용하면
do_page_fault()
처럼 의미 있는 이름으로 확인할 수 있습니다.
Symbol Table이란?
Kernel은 모든 심볼을 하나의 테이블로 관리합니다.
Kernel
↓
Symbol Table
↓
Function
Variable
Address
대표적으로 다음 정보를 포함합니다.
- 함수 이름
- 변수 이름
- 메모리 주소
- 심볼 타입
System.map이란?
System.map은 커널을 컴파일할 때 생성되는 심볼 테이블 파일입니다.
일반적으로 다음 위치에 있습니다.
/boot/System.map-커널버전
예를 들어
/boot/System.map-6.8.0
과 같은 형태입니다.
System.map 구조
예시
ffffffff81000000 T startup_64
ffffffff81000120 T start_kernel
ffffffff81001a80 T rest_init
ffffffff8100abcd T schedule
ffffffff81023456 T do_page_fault
각 행은
- 메모리 주소
- 심볼 타입
- 함수 이름
으로 구성됩니다.
Symbol Type
대표적인 Symbol Type
| 타입 | 의미 |
|---|---|
| T | Text(함수) |
| D | Initialized Data |
| B | BSS |
| R | Read Only Data |
| A | Absolute |
| U | Undefined |
가장 많이 보이는 것은 T입니다.
/proc/kallsyms란?
현재 실행 중인 Kernel의 Symbol Table입니다.
확인
cat /proc/kallsyms
일부 출력
ffffffff81000000 startup_64
ffffffff81000120 start_kernel
ffffffff81023456 do_page_fault
System.map과 매우 비슷하지만 현재 실행 중인 커널의 정보를 제공합니다.
특정 함수 검색
예를 들어
grep schedule /proc/kallsyms
또는
grep do_page_fault /proc/kallsyms
처럼 특정 함수를 검색할 수 있습니다.
주소 검색
주소를 알고 있다면
grep ffffffff81023456 /proc/kallsyms
으로 대응하는 심볼을 찾을 수 있습니다.
nm 명령
Kernel Image에서도 Symbol을 확인할 수 있습니다.
nm vmlinux
특정 함수
nm vmlinux | grep schedule
개발 시 자주 사용하는 명령입니다.
objdump 활용
함수 위치 확인
objdump -t vmlinux
특정 심볼
objdump -t vmlinux | grep do_page_fault
심볼과 함께 ELF 구조도 확인할 수 있습니다.
addr2line 활용
주소를 소스 코드 위치로 변환합니다.
addr2line -e vmlinux 주소
예시
addr2line -e vmlinux 0xffffffff81023456
결과
mm/fault.c:312
오류 발생 위치를 빠르게 찾을 수 있습니다.
Kernel Panic 분석
예시
Call Trace:
schedule
mutex_lock
do_page_fault
panic
Call Trace의 함수 이름도 Symbol을 기반으로 출력됩니다.
Symbol이 없으면
0xffffffff81023456
0xffffffff81034567
처럼 주소만 출력됩니다.
ksymoops
과거에는 ksymoops라는 도구가 많이 사용되었습니다.
현재는 대부분
- kallsyms
- addr2line
- crash
- gdb
등으로 대체되었습니다.
GDB 활용
Kernel Image 열기
gdb vmlinux
특정 함수 확인
info functions schedule
주소 확인
info address schedule
디버깅 시 매우 자주 사용하는 기능입니다.
실무에서 자주 사용하는 명령어
현재 Symbol 확인
cat /proc/kallsyms
특정 함수 검색
grep schedule /proc/kallsyms
System.map 검색
grep do_page_fault /boot/System.map-$(uname -r)
Kernel Symbol 출력
nm vmlinux
ELF Symbol 확인
objdump -t vmlinux
주소를 소스 코드로 변환
addr2line -e vmlinux 주소
실무 사례
예를 들어 운영 중인 서버에서 Kernel Oops가 발생했다고 가정해 보겠습니다.
로그에는 다음과 같은 내용이 출력됩니다.
RIP: do_page_fault+0x1a5
운영팀은 다음과 같은 절차로 분석합니다.
System.map또는/proc/kallsyms에서do_page_fault의 주소 확인addr2line을 이용해 해당 주소를 실제 소스 코드 줄 번호로 변환gdb에서 함수 내부 흐름 분석Call Trace를 함께 확인하여 어떤 함수 호출 중 오류가 발생했는지 추적- 문제를 수정한 뒤 커널을 다시 빌드하고 테스트 환경에서 재현 여부를 확인
이처럼 Kernel Symbol은 주소를 사람이 이해할 수 있는 함수와 변수 이름으로 변환해 주는 핵심 역할을 하며, 커널 디버깅과 장애 분석에서 반드시 필요한 정보입니다.
자주 묻는 질문
System.map과 /proc/kallsyms의 차이는 무엇인가요?
System.map은 커널을 빌드할 때 생성되는 정적인 심볼 파일이고, /proc/kallsyms는 현재 실행 중인 커널의 심볼 정보를 동적으로 제공합니다.
Symbol이 없으면 어떤 문제가 발생하나요?
Kernel Panic이나 Oops 로그에 함수 이름 대신 메모리 주소만 표시되어 원인 분석이 매우 어려워집니다.
addr2line은 언제 사용하나요?
Kernel Panic 로그나 Oops 메시지에서 확인한 주소를 실제 소스 코드 파일과 줄 번호로 변환할 때 사용합니다.
마무리
Linux Kernel Symbol은 메모리 주소를 함수와 변수 이름으로 연결하는 중요한 정보입니다. System.map, /proc/kallsyms, nm, objdump, addr2line 등을 활용하면 Kernel Panic, Oops, Call Trace를 훨씬 효율적으로 분석할 수 있습니다. 커널 개발자뿐 아니라 Linux 서버 운영자에게도 Symbol의 개념과 활용법은 필수적인 지식입니다.