信号学习心得

来源:互联网 发布:电子电路图制作软件 编辑:程序博客网 时间:2024/05/29 04:18
系统调用SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset,        sigset_t __user *, oset, size_t, sigsetsize) //堵塞或者撤销堵塞某些信号    =>sigprocmask SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, nset,        old_sigset_t __user *, oset)    =>sigaddsetmask(&new_blocked, new_set);SYSCALL_DEFINE2(signal, int, sig, __sighandler_t, handler)//设置信号处理函数    =>do_sigaction(sig, &new_sa, &old_sa);内核信号触发,详见LINUX内存管理部分,do_page_fault内核信号处理do_notify_resume    =>do_signal        =>signr = get_signal_to_deliver(&info, &ka, regs, NULL);            =>for (;;)                =>signr = dequeue_signal(current, &current->blocked, info);//pending队列取一个信号                =>if (!signr)//队列为空时退出                    break; /* will return 0 */                =>if (ka->sa.sa_handler != SIG_DFL) {//如果不是默认信号处理函数则退出                        /* Run the handler.  */                        *return_ka = *ka;                        if (ka->sa.sa_flags & SA_ONESHOT)                            ka->sa.sa_handler = SIG_DFL;                        break; /* will return non-zero "signr" value */                    }                =>if (sig_kernel_coredump(signr))//如果信号比较严重,则coredump,增加调试信息                    do_coredump(info->si_signo, info->si_signo, regs);                        =>retval = binfmt->core_dump(&cprm);                            static struct linux_binfmt elf_format = {                                .module     = THIS_MODULE,                                .load_binary    = load_elf_binary,                                .load_shlib = load_elf_library,                                .core_dump  = elf_core_dump,                                .min_coredump   = ELF_EXEC_PAGESIZE,                            };                            #ifdef CONFIG_ELF_CORE                            static int elf_core_dump(struct coredump_params *cprm);                            #else                            #define elf_core_dump   NULL                            #endif                =>do_group_exit(info->si_signo);        =>handle_signal(signr, &info, &ka, oldset, regs)            =>ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, ka, regs, sig, oldset, info);                    =>setup_rt_frame //arch\mips\kernel):   .setup_rt_frame = setup_rt_frame,                        =>frame = get_sigframe(ka, regs, sizeof(*frame));                        =>/* Create siginfo.  */                        err |= copy_siginfo_to_user(&frame->rs_info, info);//设置信号处理函数栈帧                        =>regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;//挂接信号处理函数,handle_signal返回时调用sa_handler

内核在允许进程恢复用户态执行之前,检测进程TIF_SIGPENDING标志的数值,每当内核处理完1个中断/异常时,就检查是否存在进程挂起信号
文章参考
http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html

监控进程:可以通过epoll与所有进程通信,一旦通信是吧,可以调用waitpid获取状态

原创粉丝点击