gpt4 book ai didi

c - Longjmp 超出信号处理程序?

转载 作者:太空狗 更新时间:2023-10-29 16:32:13 24 4
gpt4 key购买 nike

来自问题:

Is it good programming practice to use setjmp and longjmp in C?

留下的两条评论说:

"You can't throw an exception in a signal handler, but you can do a longjmp safely -- as long as you know what you are doing. – Dietrich Epp Aug 31 at 19:57 @Dietrich: +1 to your comment. This is a little-known and completely-under-appreciated fact. There are a number of problems that cannot be solved (nasty race conditions) without using longjmp out of signal handlers. Asynchronous interruption of blocking syscalls is the classic example."

我的印象是内核在遇到异常情况(例如除以 0)时调用信号处理程序。此外,只有在您专门注册它们时才会调用它们。

这似乎暗示(对我来说)它们不是通过您的正常代码调用的。

继续那个想法……据我所知,setjmp 和 longjmp 用于将堆栈折叠到先前的点和状态。我不明白在调用信号处理程序时如何折叠堆栈,因为它是从内核作为一次性情况调用的,而不是从您自己的代码中调用的。信号处理程序堆栈中的下一个东西是什么!?

最佳答案

内核“调用”信号处理程序的方式是中断线程,将信号掩码和处理器状态保存在堆栈上的 ucontext_t 结构中(下面,关于向下增长的实现) 中断代码的堆栈指针,并在信号处理程序的地址重新开始执行。内核不需要跟踪任何“此进程处于信号处理程序”状态;这完全是创建新调用框架的结果。

如果被中断的线程正在进行系统调用,内核将退出内核空间代码并调整返回地址以重复系统调用(如果为信号设置了SA_RESTART并且系统调用是可重启的)或将 EINTR 放入返回码(如果不可重启)。

需要注意的是,longjmp 是异步信号不安全的。这意味着如果信号中断了另一个异步信号不安全函数,如果您从信号处理程序调用它,它会调用未定义的行为。但是只要被中断的代码不使用库函数,或者只使用标记为异步信号安全的库函数,从信号处理程序调用 longjmp 就是合法的。

最后,我的答案是基于 POSIX,因为问题被标记为 unix。如果问题只是关于纯 C,我怀疑答案会有所不同,但是如果没有 POSIX,信号就毫无用处......

关于c - Longjmp 超出信号处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7334595/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com