Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

76235
1036
103646


[리눅스커널][시스템콜] ftrace로 시스템 콜 인자 디버깅하기 11장. 시스템 콜

ftrace는 시스템 콜 디버깅을 위한 이벤트를 제공합니다.
sys_enter, sys_exit 이라는 ftrace 이벤트를 쓰면 시스템 콜 동작을 확인할 수 있습니다.

위 이벤트를 키면 다음과 같은 시스템 콜 디버깅 정보를 출력합니다.
1> 시스템 콜 번호
2> 시스템 콜이 실행와 종료 시각
3> 시스템 콜 핸들러 함수로 전달된 인자

sys_enter와 sys_exit ftrace 이벤트는 어떻게 설정할 수 있을까요?

다음 명령어로 sys_enter와 sys_exit 이벤트를 키는 enable 파일을 1로 써주면 됩니다.
echo 1 > /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/enable
echo 1 > /sys/kernel/debug/tracing/events/raw_syscalls/sys_exit/enable

부팅할 때 이 값들은 기본으로 0으로 설정돼 있습니다.

시스템 콜을 ftrace로 설정하기 위한 코드를 다음과 같이 셸 스크립트 파일로 저장하면 쉽게 ftrace 설정을 할 수 있습니다.
#!/bin/bash

echo  > /sys/kernel/debug/tracing/set_event
sleep 1

echo 0 > /sys/kernel/debug/tracing/tracing_on
sleep 1

echo nop > /sys/kernel/debug/tracing/current_tracer
sleep 1"

echo 1 > /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/enable
echo 1 > /sys/kernel/debug/tracing/events/raw_syscalls/sys_exit/enable
sleep 1

echo 1 > /sys/kernel/debug/tracing/tracing_on
sleep 1

위 셸 스크립터 파일을 실행해서 시스템 콜 이벤트를 킨 다음에 ftrace 로그를 받습니다.
ftrace 로그를 열어보면 다음 패턴의 메시지를 볼 수 있습니다.
1 bash-887  [000] 11824.891592: sys_enter: NR 120 (1200011, 0, 0, 0, 76f88068, 0)
2 bash-887  [000] 11824.893365: sys_exit: NR 120 = 894
3 bash-887  [000] 11824.893835: sys_enter: NR 3 (3, 7ec6b0f0, 200, 0, 76f71000, 0)
4 bash-887  [000] 11824.893852: sys_exit: NR 3 = 512

먼저 sys_enter와 sys_exit 메시지의 의미를 확인해 보겠습니다.

1번째와 3번째 줄 로그에 있는 sys_enter란 메시지는 시스템 콜 실행 시작을 나타냅니다.
다음 2번째와 4번째 줄 로그에서 출력하는 sys_exit 메시지는 시스템 콜 실행이 끝나는 동작을 출력합니다.

다음 시스템 콜 번호를 확인해 보겠습니다.

1번째 줄 로그에서 "NR 120" 메시지는 시스템 콜 번호를 의미합니다.
3번째 줄 로그는 3번 시스템 콜이 실행했음을 알 수 있습니다.

120번과 3번에 대응하는 시스템 콜 핸들러 함수는 무엇일까요?

POSIX에서 정의한 시스템 콜 번호는 다음 경로 해더 파일에서 확인할 수 있습니다.
[usr/include/arm-linux-gnueabihf/asm/unistd.h]
#define __NR_read (__NR_SYSCALL_BASE+  3)
...
#define __NR_clone (__NR_SYSCALL_BASE+120)

시스템 콜 번호 3번에 대한 시스템 콜 핸들러는 sys_read() 함수 그리고 120번 시스템 콜 핸들러는 sys_clone임을 알 수 있습니다.

ftrace 시스템 콜 이벤트는 시스템 콜 핸들러에 전달하는 인자값을 출력합니다.
이번에는 시스템 콜 핸들러에 전달한 인자의 의미를 살펴보겠습니다.

먼저 다음 로그에 전달된 인자를 살펴봅시다.
sys_enter: NR 120 (1200011, 0, 0, 0, 76f88068, 0)

clone() 리눅스 저수준 함수에 대한 시스템 콜 핸들러는 sys_clone() 함수입니다.
1 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
2 int __user *, parent_tidptr,
3 unsigned long, tls,
4 int __user *, child_tidptr)
5
6 long sys_clone(unsigned long clone_flags, unsigned long newsp, int * parent_tidptr, unsigned long tls, int * child_tidptr)

unsigned long clone_flags = 1200011
unsigned long newsp = 0x0
int * parent_tidptr = 0x0
unsigned long tls = 0x0
int * child_tidptr = 0x76f88068

"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)


#Reference: 시스템 콜
시스템 콜 주요 개념 소개
유저 공간에서 시스템 콜은 어떻게 발생할까
시스템 콜 핸들러는 어떤 동작을 할까? 
시스템 콜 실행 완료 후 무슨 일을 할까?
시스템 콜 관련 함수  
시스템 콜 디버깅  



핑백

덧글

댓글 입력 영역