linux内核中的信号机制--信号处理
时间:11-22
来源:互联网
点击:
- regs->regs->ARM_lr=retcode;//返回地址,当用户态信号处理函数结束时,就会把这个地址作为返回地址
- regs->ARM_pc=handler;//信号处理函数
- regs->ARM_cpsr=cpsr;
- return0;
- }
当setup_frame()返回后,一切准备就绪,因此可以从内核态返回了,这样就顺利过渡到用户态的信号处理函数。当这个函数处理结束后,会通过retcode再次进入内核态,现在我们看看retcode是如何处理的,下面的代码选自glibc(2.3.2):
[plain]view plaincopyprint?
- #include
- /*IfnoSA_RESTORERfunctionwasspecifiedbytheapplicationweuse
- oneofthese.Thisavoidstheneedforthekerneltosynthesiseareturn
- instructiononthestack,whichwouldinvolveexpensivecacheflushes.*/
- ENTRY(__default_sa_restorer)
- swiSYS_ify(sigreturn)
- #ifdef__NR_rt_sigreturn
- ENTRY(__default_rt_sa_restorer)
- swiSYS_ify(rt_sigreturn)
- #defineSYS_ify(syscall_name)(__NR_##syscall_name)
下面具体看看sys_sigreturn()的定义:
[plain]view plaincopyprint?
- asmlinkageintsys_sigreturn(structpt_regs*regs)
- {
- structsigframe__user*frame;
- sigset_tset;
- /*Alwaysmakeanypendingrestartedsystemcallsreturn-EINTR*/
- current_thread_info()->restart_block.fn=do_no_restart_syscall;
- /*
- *Sincewestackedthesignalona64-bitboundary,
- *thenspshouldbewordalignedhere.Ifits
- *not,thentheuseristryingtomesswithus.
- */
- if(regs->ARM_sp&7)
- gotobadframe;
- frame=(structsigframe__user*)regs->ARM_sp;
- if(!access_ok(VERIFY_READ,frame,sizeof(*frame)))
- gotobadframe;
- if(__get_user(set.sig[0],&frame->sc.oldmask)
- ||(_NSIG_WORDS>1
- &&__copy_from_user(&set.sig[1],&frame->extramask,
- sizeof(frame->extramask))))
- gotobadframe;
- sigdelsetmask(&set,~_BLOCKABLE);
- spin_lock_irq(¤t->sighand->siglock);
- current->blocked=set;
- recalc_sigpending();
- spin_unlock_irq(¤tt->sighand->siglock);
- if(restore_sigcontext(regs,&frame->sc,&frame->aux))
- gotobadframe;
- /*SendSIGTRAPifweresingle-stepping*/
- if(current->ptrace&PT_SINGLESTEP){
- ptrace_cancel_bpt(current);
- send_sig(SIGTRAP,current,1);
- }
- returnregs->ARM_r0;
- badframe:
- force_sig(SIGSEGV,current);
- return0;
- }
[plain]view plaincopyprint?
- staticint
- restore_sigcontext(structpt_regs*regs,structsigcontext__user*sc,
- structaux_sigframe__user*aux)
- {
- interr=0;
- __get_user_error(regs->ARM_r0,&sc->arm_r0,err);
- __get_user_error(regs->ARM_r1,&sc->arm_r1,err);
- __get_user_error(regs->ARM_r2,&sc->arm_r2,err);
- __get_user_error(regs->ARM_r3,&sc->arm_r3,err);
- __get_user_error(regs->ARM_r4,&sc->arm_r4,err);
- __get_user_error(regs->ARM_r5,&sc->arm_r5,err);
- __get_user_error(regs->ARM_r6,&sc->arm_r6,err);
- __get_user_error(regs->ARM_r7,&sc->arm_r7,err);
- __get_user_error(regs->ARM_r8,&sc->arm_r8,err);
- __get_user_error(regs->ARM_r9,&sc->arm_r9,err);
- __get_user_error(regs->ARM_r10,&sc->arm_r10,err);
- __get_user_error(regs->ARM_fp,&sc->arm_fp,err);
- __get_user_error(regs->ARM_ip,&sc->arm_ip,err);
- __get_user_error(regs->ARM_sp,&sc->arm_sp,err);
- __get_user_error(regs->ARM_lr,&sc->arm_lr,err);
- __get_user_error(regs->ARM_pc,&sc->arm_pc,err);
- __get_user_error(regs->ARM_cpsr,&sc->arm_cpsr,err);
- err|=!valid_user_regs(regs);
- #ifdefCONFIG_IWMMXT
- if(err==0&&test_thread_flag(TIF_USING_IWMMXT))
- err|=restore_iwmmxt_context(&aux->iwmmxt);
- #endif
- #ifdefCONFIG_VFP
- //if(err==0)
- //err|=vfp_restore_state(&aux->vfp);
- #endif
- returnerr;
- }
linux内核信号机制信号处 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)