从操作系统的角度来看,异常是如何工作的?
来自C ++,我可以从程序员的角度理解异常 抛出异常时,堆栈开始展开,每个激活记录都有机会捕获并处理异常。
但是他们的责任是首先抛出异常吗?
这是两个崩溃的程序,说明了我的不确定性。
int main(){
int i = 1/0; //did the OS tell the process to end?
return 0;
}
#include <exception>
int main(){
throw 11; //did the process tell the OS it needs to end?
return 0;
}
答案 0 :(得分:12)
C ++异常是语言的一部分,由语言标准定义,并由编译器和运行时库实现。 CPU检测到其他exceptions
,如除以零或取消引用NULL指针,两者都是语言标准中Undefined Behavior的示例。那些是处理器术语中的faults
,并且在x86上例如触发fault handler
,然后由OS提供服务。然后操作系统可以选择将该故障报告给导致它的进程,在Unix上,这是通过signals
完成的。例如,如果您的进程为signal handler
安装了SIGSEGV
,那么当进程解引用NULL指针时,它可以处理CPU生成的错误...该机制与由C ++定义的C ++异常分开。语言。
在您的示例中,当C ++程序throws
异常这完全由编译器生成的代码和语言运行时库处理时,不需要内核调用,并且处理器不会生成硬件错误。
答案 1 :(得分:8)
答案 2 :(得分:6)
由于我只知道一个或两个用C ++编写的操作系统,而且我知道更好的操作系统,根本没有正式使用异常,这几乎排除了操作系统抛出的异常。
三个主要操作系统(Linux,Windows,MacOS X)以及所有形式的Unix(AIX,Solaris,HP-UX等)都是用C语言编写的,几乎所有其他商用操作系统都是用用汇编语言编写,所以不能抛出C ++类型的异常[这并不是说没有软件驱动的异常,只是它们不是你在C ++中用“try / catch”捕获的异常类型而没有某种翻译]。
在第一个例子中,操作系统肯定涉及[在所有操作系统中我知道它们如何工作],因为除以零会导致所有具有除法功能的机器上的硬件异常,因此操作系统将需要参与其中。此外,无论是C ++,C还是在汇编程序中编写相同的东西,它都会以相同的方式编译和失败。对于大多数操作系统,它们会向程序发送信号,但由于您没有处理信号的代码,因此您的代码很可能只是中止,告诉操作系统发生了一些奇怪的事情而且它正在放弃,甚至不打算放松堆栈。
在第二种情况下,操作系统根本不参与。在对main的调用周围有一个“try-catch”块,其中写着“哎呀,有人投掷了一些未捕获的东西,让我们退出”。涉及操作系统的唯一部分是“退出此过程”,当然这需要由操作系统完成,尽管我相信大多数操作系统,只是从“应用程序的起始地址”返回也将也有同样的效果。