c – 在linux中处理SIGBUS
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c – 在linux中处理SIGBUS,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1743字,纯文字阅读大概需要3分钟。
内容图文
在我的一个程序中,当尝试访问未能获取内存页面的mmap-ed内存位置(因为底层物理内存耗尽)并且程序因SIGBUS而崩溃时,我会点击“SIGBUS”.
我打算注册一个SIGBUG信号处理程序以避免崩溃.但是,我不想从SIGBUS处理程序退出()程序.我试图看看是否有任何方式优雅地报告ENOMEM并继续该程序与其他工作.
我可以这样做吗?代码如下所示:
mem_p->head = MY_HEAD_MAGIC; /* this line could trigger SIGBUS */
if (sigbus_happened) {
sigbus_happened = FALSE;
do_something_else();
return ENOMEM;
}
和信号处理程序:
void signal_handler (int sig)
{
if (sig == SIGBUS)
sigbus_happened = TRUE;
}
上述工作会不会崩溃?
谢谢.
解决方法:
您显示的代码可能会违背您的预期.这是因为编译器可以自由安排代码,以便在分配mem_p-> head之前“记住”sigbus_happened的值.因此,即使信号处理程序执行,您的代码也可能无法检测到该标志已被设置.至少,您需要使变量变为volatile.
更好的方法是简单地检查mmap()调用是否失败.您可以通过检查调用是否返回值MAP_FAILED来执行此操作.如果调用失败,请勿尝试访问指针值.
您尝试捕获SIGBUS会提醒异常处理. C没有C样式异常处理(尽管存在模仿它们的宏包,例如cexcept).但是,一种方式是以一种更像是异常工作的方式来使用setjmp()和longjmp()来跟随你的模型. setjmp()保存现有的堆栈上下文并返回0.longjmp()将代码返回到保存的上下文,并使setjmp()返回非0值.
从信号处理程序中,最好使用POSIX sigsetjmp()和siglongjmp(),以便在调用信号处理程序之前被C运行时或操作系统阻止的任何信号都会重置为返回到保存的上下文时的值.
jmp_buf *sigbus_jmp; // global
void signal_handler (int sig)
{
if (sig == SIGBUS) {
if (sigbus_jmp) siglongjmp(*sigbus_jmp, 1);
// no one to catch the error, so abort
abort();
}
}
//...
jmp_buf sigbus_jmpbuf;
sigbus_jmp = &sigbus_jmpbuf;
if (sigsetjmp(sigbus_jmpbuf, 1) == 0) {
// try
mem_p->head = MY_HEAD_MAGIC; /* this line could trigger SIGBUS */
} else {
// catch
do_something_else();
return ENOMEM;
}
sigbus_jmp = 0;
内容总结
以上是互联网集市为您收集整理的c – 在linux中处理SIGBUS全部内容,希望文章能够帮你解决c – 在linux中处理SIGBUS所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。