linux手册翻译——sigreturn(2)


sigreturn, rt_sigreturn - 从信号处理函数返回,并清除栈帧

int sigreturn(...);


如果 Linux 内核确定某个进程有一个未阻塞的信号等待处理,那么当该进程下一次从内核态转换回用户态时(例如,从系统调用返回时或当进程被重新调度到 CPU 上时),它会创建用户空间堆栈、或定义的备用堆栈上的一个栈帧,用于保存各种进程上下文(处理器状态字、寄存器、信号掩码和信号堆栈设置)。

之后将会调用信号处理程序,信号处理程序返回时,调用“signal trampoline”的用户空间代码,此代码实现了类似于中断返回的操作,以帮助返回执行用户程序,其工作如下,更详细的描述见我之前翻译的signal

sigreturn() 调用将撤消已完成的所有操作:

  • 更改进程的信号掩码
  • 切换信号堆栈(请参阅 sigaltstack(2))

sigreturn() 将使用先前保存在用户空间堆栈上的信息:

  • 恢复进程的信号掩码
  • 切换堆栈
  • 恢复进程的上下文(处理器标志和寄存器,包括堆栈指针和指令指针)

以便进程恢复在被信号中断的地方执行。

sigreturn() 的存在只是为了允许信号处理程序的实现。 永远不应该直接调用它。 (实际上,GNU C 库中的简单 sigreturn() 包装器仅返回 -1,将 errno 设置为 ENOSYS。)传递给 sigreturn() 的参数(如果有)的详细信息因架构而异。 (在某些体系结构上,例如 x86-64, sigreturn() 不带参数,因为它需要的所有信息都可以在先前由内核在用户空间堆栈上创建的堆栈帧中获得。)

曾几何时,UNIX 系统将信号蹦床代码放置到用户堆栈中。 如今,用户堆栈的页面受到保护以禁止代码执行。 因此,在当代 Linux 系统上,根据体系结构,信号蹦床代码存在于 vdso(7) 或 C 库中。 在后一种情况下,C 库的 sigaction(2) 包装函数通过将 Trampoline 代码的地址放在 sigaction 结构的 sa_restorer 字段中来通知内核该蹦床代码的位置,并在 sa_flags 字段中设置 SA_RESTORER 标志。也就是说,这个Trampoline代码是C库封装好的,并且在调用sigaction时,自动(因为sigaction函数本身也是由C库封装)将地址写入到sa_restorer中。

保存的进程上下文信息放置在 ucontext_t 结构中(参见 )。 该结构作为通过带有 SA_SIGINFO 标志的 sigaction(2) 建立的处理程序的第三个参数在信号处理程序中可见。

在其他一些 UNIX 系统上,信号蹦床的操作略有不同。 特别是,在某些系统上,在转换回用户模式时,内核将控制权传递给蹦床(而不是信号处理程序),并且蹦床代码调用信号处理程序(然后在处理程序返回后调用 sigreturn())。

你可能感兴趣的:(linux手册翻译——sigreturn(2))