微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C ++异常框架是否需要内核支持?

如何解决C ++异常框架是否需要内核支持?

我正在阅读有关C ++中的异常支持的信息,可能结果也适用于其他语言。

https://wiki.osdev.org/C%2B%2B_Exception_Support

http://www.ucw.cz/~hubicka/papers/abi/node25.html

发生了很多事情,我有点不知所措。我的问题是在展开过程中,C ++是否需要内核的帮助(例如,如注释中提到的 setjmp / longjmp ,这两个函数不涉及内核,但是我的问题仍然相同)?还是整个过程只发生在用户空间中?

我可以理解本地线程的展开(想想setjmp / longjmp),但是无法掌握如何对远程线程进行展开。

如果所有轻松的魔术都发生在用户空间中,那么一个线程如何在没有内核帮助的情况下修改一个有故障的线程以将其发送给处理代码?由于我认为线程上下文信息(任务结构)位于内核内部,并且不允许直接从用户空间进行修改,而无需访问线程上下文,因此如何实现呢?谢谢!


更新:看来我对任务结构有一些基本的误解。刚进入有关信号处理(signal handlers)(http://users.cms.caltech.edu/~donnie/cs124/lectures/CS124Lec15.pdf)的幻灯片时,进入信号处理程序后,内核堆栈为空,所有上下文信息都位于用户堆栈中。我想一个人可以使用信号与其他故障线程进行通讯来放松吗?如果是这样,这是否意味着C ++异常支持需要内核帮助,因为生成信号是内核调用


更新:就问题而言,我对保罗的回答感到满意。我想从广义上总结我对该主题的理解,根据我对评论/答案的阅读,如果我错了,请指正。

C ++异常框架未指定特定的实现方法,下面的摘要是我认为这是“常见的”。

有三种异常对象来源,实现的展开如下所示:

+------------------------------------------------+--------------------------------------------------------------------------+
|                exception source                |                             unwinding method                             |
+------------------------------------------------+--------------------------------------------------------------------------+
| a) exception created by `throw`                | via code to walk the stack and assembly to transfer control to call site |
| b) exception created by hardware e.g. SIGFPE   | via synchronous signal,and code to walk the stack                       |
|                                                | and assembly to transfer control to call site                            |
| c)* exception created by remote process/thread | via asynchronous signal,and code to walk the stack                      |
|                                                | and assembly to transfer control to call site                            |
+------------------------------------------------+--------------------------------------------------------------------------+

*对于情况c),我不确定是否存在现实世界中的使用要求由外部进程创建并在本地处理的异常,这不适合throw / {{ 1}}的语义(至少是可行的),我在这里仅出于完整性考虑。

解决方法

否。

所有这些都在C ++运行时库中实现(对于GCC,至少在Linux上,它是libgcc_s.so)。这要求代码在堆栈中移动以查找捕获块,并且如果找到,则需要一些机器代码才能跳入此类块。如前所述,setjmp / longjmp也不需要内核。

更新:请勿混淆C ++异常和信号。如果您想了解更多 C ++异常的工作方式是一个好的开始(如果您熟悉阅读 汇编程序)将使用godbolt查看生成的汇编程序,以查找一些引发并捕获异常的简单函数。当心 浮点异常(FPE)实际上是信号。

C ++异常与setjmp / longjmp +信号之间的一个区别是 控制流程。后两者通过一种“调用”(保存上下文)和“返回”(保存上下文)来实现“恢复语义”。另一方面,C ++异常实现了“终止语义”,并且无法返回到throw的站点。

信号分为两类:立即发送同步信号(如SIGBUS)和在下一个调度程序时间片发送的异步信号(如SIGINT)。两种情况都通过内核。没有真正的 从用户的角度来看。

线程不能与其他任何进行堆栈操作的东西(setjmp / longjmp和信号)很好地混合。特别是多线程应用程序可以 在任何线程上接收异步信号。为了使其更易于管理, 通常的做法是使用pthread_sigmask屏蔽所有信号 除了一个线程之外的所有线程都是信号处理线程。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?