Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

8179
1390
307630


[리눅스커널][시그널] 시그널 생성: __send_signal() 커널 함수 분석 12. 시그널

누군가 ‘시그널을 생성하는 핵심 함수가 무엇인가?’ 라고 질문을 한다면 __send_signal() 함수라고 대답할 수 있습니다. 그렇습니다. 시그널을 생성하는 핵심 함수는 __send_signal() 입니다. 

이제부터 __send_signal() 함수 코드를 분석하겠습니다.

https://elixir.bootlin.com/linux/v4.19.30/source/kernel/signal.c
1 static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
int group, int from_ancestor_ns)
3 {
4 struct sigpending *pending;
5 struct sigqueue *q;
6 int override_rlimit;
7 int ret = 0, result;
8
9 assert_spin_locked(&t->sighand->siglock);
10
11 result = TRACE_SIGNAL_IGNORED;
12 if (!prepare_signal(sig, t,
13 from_ancestor_ns || (info == SEND_SIG_FORCED)))
14 goto ret;
15
16 pending = group ? &t->signal->shared_pending : &t->pending;
17
18 result = TRACE_SIGNAL_ALREADY_PENDING;
19 if (legacy_queue(pending, sig))
20 goto ret;
...
21
22 q = __sigqueue_alloc(sig, t, GFP_ATOMIC, override_rlimit);
23 if (q) {
24 list_add_tail(&q->list, &pending->list);
25 switch ((unsigned long) info) {
26 case (unsigned long) SEND_SIG_NOINFO:
27    q->info.si_signo = sig;
28    q->info.si_errno = 0;
29    q->info.si_code = SI_USER;
30    q->info.si_pid = task_tgid_nr_ns(current,
31 task_active_pid_ns(t));
32    q->info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
33    break;
34 case (unsigned long) SEND_SIG_PRIV:
35    q->info.si_signo = sig;
36    q->info.si_errno = 0;
37    q->info.si_code = SI_KERNEL;
38    q->info.si_pid = 0;
39    q->info.si_uid = 0;
40 break;
41 default:
42    copy_siginfo(&q->info, info);
43    if (from_ancestor_ns)
44 q->info.si_pid = 0;
45 break;
46 }
47
48 userns_fixup_signal_uid(&q->info, t);
49
50 } else if (!is_si_special(info)) {
51 if (sig >= SIGRTMIN && info->si_code != SI_USER) {
52 result = TRACE_SIGNAL_OVERFLOW_FAIL;
53 ret = -EAGAIN;
54 goto ret;
55 } else {
56 result = TRACE_SIGNAL_LOSE_INFO;
57 }
58 }
59
60 out_set:
61 signalfd_notify(t, sig);
62 sigaddset(&pending->signal, sig);
63 complete_signal(sig, t, group);
64 ret:
65 trace_signal_generate(sig, info, t, group, result);
66 return ret;
67 }

먼저 __send_signal() 함수 분석에 앞서 이 함수가 어떤 일을 하는지 알아볼까요?
__send_signal() 함수 세부 처리 과정은 5단계로 분류할 수 있습니다.

1 단계:  시그널 예외 처리
2 단계: 시그널 펜딩 리스트에 시그널 정보를 저장한 후 시그널을 받을 프로세스 태스크 디스크립터에 써줌
3 단계: 시그널을 받을 프로세스 스택 최상단 주소에 있는 struct thread_info 구조체 flags에 _TIF_SIGPENDING 플래그를 써줌
4. 시그널을 받을 프로세스를 깨움
5. 시그널 ftrace 로그 출력


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

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

repository:
http://rousalome.egloos.com/10025756

핑백

덧글

댓글 입력 영역