执行默认信号处理程序
我编写了一个应用程序,其中我为 linux 中的不同信号注册了多个信号处理程序。 进程接收到信号后,控制权将转移到我注册的信号处理程序。在这个信号处理程序中,我做了一些我需要做的工作,然后我想调用默认信号处理程序,即 SIF_DFL
或 SIG_IGN
。 然而,SIG_DFL
和SIG_ING
都是宏,分别扩展为数值0和1,这是无效的函数地址。
有什么方法可以调用默认操作,即 SIG_DFL
或 SIG_IGN
吗?
为了达到 SIG_DFL
或 SIG_ING
的效果,我分别调用 exit(1) 和不执行任何操作。但对于像 SIGSEGV 这样的信号,我也希望有核心转储。 一般来说,我希望我的默认行为与 SIG_DFL
相同,并忽略相同 SIG_IGN
的行为,就像操作系统所做的那样。
I have written an application where i have registered number of signal handler for different signals in linux .
After process receives the signal the control is transferred to the signal handler i had registered. In this signal handler i do some work which i need to do, and then i would like to call the default signal hander i.e SIF_DFL
or SIG_IGN
.
However, SIG_DFL
and SIG_ING
are both macros which expand to numeric values 0 and 1 respectively, which are invalid function addresses.
IS there any way i can call default actions i.e SIG_DFL
or SIG_IGN
?
In order to achieve the effect of SIG_DFL
or SIG_ING
i call exit(1) and do nothing , respectively . But for signals like SIGSEGV
i also would like to have core dump .
In general i would want to my default behavior to be same as SIG_DFL
and ignore behavior same SIG_IGN
, the way Operating system would do .
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
GNU C 库参考手册有一整章解释关于信号处理的一切。
当您安装自己的处理程序时,您始终会获得先前设置的信号处理程序(函数指针)(请参阅
signal()
或sigaction()
的联机帮助页)。一般规则是,您始终可以重置到前一个处理程序并再次
raise()
信号。一般规则有一个缺点:映射到信号的硬件异常通常被分配给导致异常的特定指令。因此,当您再次发出信号时,相关指令与原来的指令不同。这可能但不应该损害其他信号处理程序。
另一个缺点是,每个升高的信号都会导致大量的处理时间。为了防止过度使用
raise()
,您可以使用以下替代方法:如果是
SIG_DFL
,函数指针指向地址0
(这显然不是有效地址)。因此,您必须重置处理程序并再次raise()
信号。SIG_IGN
的值为1
(也是一个无效地址)。在这里你可以直接返回(什么也不做)。否则(
SIG_IGN
和SIG_DFL
)您已收到有效的函数指针,并且您可以直接调用处理程序,<前><代码>其他
{
先前的处理程序(sig);
}
您还必须考虑不同的 API(请参阅
signal()
和sigaction()
的联机帮助页)。The GNU C Library Reference Manual has a whole chapter explaining everything about signal handling.
You always get the previously set signal handler (a function pointer) when you install your own handler (see manpages for
signal()
orsigaction()
).The general rule is, that you can always reset to the previous handler and
raise()
the signal again.There is one disadvantage of the general rule: Hardware exceptions which are mapped to signals are usually assigned to a certain instruction which caused the exception. So, when you raise a signal again, the associated instruction is not the same as originally. This can but should not harm other signal handlers.
Another disadvantage is, that each raised signal causes a lot of processing time. To prevent excessive use of
raise()
you can use the following alternatives:In case of
SIG_DFL
the function pointer points to address0
(which is obviously no valid address). Thus, you have to reset the handler andraise()
the signal again.SIG_IGN
has value1
(also an invalid address). Here you can just return (do nothing).Otherwise (neither
SIG_IGN
norSIG_DFL
) you have received a valid function pointer and you can call the handler directly,Of course, you have to consider the different APIs as well (see manpages for
signal()
andsigaction()
).您可以保存之前的处理程序,然后在适当的时候调用它。
安装处理程序。确保保存旧处理程序
在新处理程序中,调用旧处理程序
您不需要再次引发它或做任何混乱的事情;只需调用旧的处理程序(当然,由于您保存了
sigaction
,因此您可以访问旧的配置等等)。You can save the previous handler and then call it when the time is right.
Install handler. Make sure you save old handler
In your new handler, call the old handler
You don't need to raise it again or do any messy stuff; simply call the old handler (of course, since you saved the
sigaction
you have acces to the old disposition and so on).通常的方法是重置信号处理程序,然后再次
raise()
信号:下面是一个 SIGINT 处理程序示例:
The usual approach is to reset the signal handler and then
raise()
the signal again:Here's an example SIGINT handler:
鉴于信号处理程序是在内核中实现的,我看到的唯一方法是
raise()
信号Given the signal handlers are implemented in kernel, the only way I see is to
raise()
the signal again