ARM Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

203239
1625
172600


[리눅스커널] 시그널: 커널 공간 sys_rt_sigsuspend() 함수 분석하기 12. 시그널

유저 공간에서 sigsuspend() 함수를 호출하면 커널에서 어떤 동작을 하는지 다음 그림을 보면서 알아봅시다.
 
[그림 12.13] 유저 공간에서 sigsuspend() 함수 호출 시 실행 흐름도

위 그림에서 보이듯 유저 공간에서 sigsuspend() 함수를 호출하면 해당 시스템 콜 핸들러인 sys_rt_sigsuspend() 함수가 호출됩니다. 

sys_rt_sigsuspend() 함수 선언부는 다음과 같습니다.
[https://github.com/raspberrypi/linux/blob/rpi-4.19.y/include/linux/syscalls.h]
asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);

함수 인자 속성은 다음과 같습니다.
sigset_t __user *unewset: 블로깅하려는 시그널 속성
size_t sigsetsize: 시그널 설정 크기

sys_rt_sigsuspend() 함수 선언부를 확인했으니 구현부를 확인합시다.
[https://github.com/raspberrypi/linux/blob/rpi-4.19.y/kernel/signal.c]
1 SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
2 {
3 sigset_t newset;
4
5 /* XXX: Don't preclude handling different sized sigset_t's.  */
6 if (sigsetsize != sizeof(sigset_t))
7 return -EINVAL;
8
9 if (copy_from_user(&newset, unewset, sizeof(newset)))
10 return -EFAULT;
11 return sigsuspend(&newset);
12 }

9번째 줄 코드를 보겠습니다. 유저 공간에서 전달된 시그널 정보인 unewset 인자 포인터를 newset 지역 변수에 저장합니다.

다음 11번째 줄 코드는 sigsuspend() 함수를 호출합니다. sys_rt_suspend() 함수는 유저 공간에서 설정된 시그널 정보를 newest 블락 지역변수에 저장하고 sigsuspend() 함수를 호출합니다.

다음으로 분석할 함수는 sigsuspend() 함수입니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/kernel/signal.c]
1 static int sigsuspend(sigset_t *set)
2 {
3 current->saved_sigmask = current->blocked;
4 set_current_blocked(set);
5
6 while (!signal_pending(current)) {
7 __set_current_state(TASK_INTERRUPTIBLE);
8 schedule();
9 }
10 set_restore_sigmask();
11 return -ERESTARTNOHAND;
12 }

4번째 줄 코드를 봅시다.
4 set_current_blocked(set);

함수 인자로 전달된 sigset_t *set 인자에 시그널 블록을 설정합니다. 이 코드가 sys_pause() 함수와 다른 점입니다.

6~9번째 줄 코드를 보겠습니다.

현재 프로세스에서 펜딩된(처리할) 시그널이 없을 때까지 while 문을 구동합니다.
7번째 줄 코드를 보면 현재 프로세스 상태를 TASK_INTERRUPTIBLE로 바꾼 다음 휴면에 진입합니다.

T32로 본 해당 프로세스 콜 스택은 다음과 같습니다. 
-000|context_switch(inline)
-000|__schedule()
-001|set_ti_thread_flag(inline)
-001|set_restore_sigmask(inline)
-001|sigsuspend(?)
-002|SYSC_rt_sigsuspend(inline)
-002|sys_rt_sigsuspend(?, ?)
-003|ret_fast_syscall(asm)

이제 이번 절에서 배운 내용을 정리해볼까요?  
유저 공간에서 시그널을 설정하는 함수를 호출하면 커널 공간에서 시그널을 설정하는 함수가 실행함
유저 공간에서 sigsuspend() 함수를 호출하면 커널 공간에서 sigset_t로 설정한 시그널을 블록하고 시그널 전달을 기다리며 휴면에 진입

#Referene 시그널
시그널이란
시그널 설정은 어떻게 할까
시그널 생성 과정 함수 분석
프로세스는 언제 시그널을 받을까
시그널 전달과 처리는 어떻게 할까?
시그널 제어 suspend() 함수 분석 
시그널 ftrace 디버깅

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



핑백

덧글

댓글 입력 영역