17

从操作系统的角度来看,异常是如何工作的?

来自 C++,我可以从程序员的角度理解异常。
当抛出异常时,堆栈开始展开,每个激活记录都有机会捕获和处理异常。

但是首先抛出异常是谁的责任呢?

  1. 是操作系统向进程发送触发器,告诉它进入“异常处理状态”吗?
  2. 进程是否在它自己的程序空间中调用和处理异常,对操作系统来说是不发音的?

这里有两个崩溃的程序说明了我的不确定性。

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;
}
4

3 回答 3

12

C++ 异常是语言的一部分,由语言标准定义,并由编译器和运行时库实现。CPU 检测到的还有其他exceptions,例如除以零或取消引用 NULL 指针,两者都是语言标准中未定义行为的示例。这些faults在处理器术语中,例如在 x86 上触发 afault handler然后由操作系统提供服务。然后,操作系统可以选择将该故障报告给导致它的进程,在 Unix 上,这是使用signals. signal handler例如,如果您的进程安装了一个SIGSEGV,它可以处理当进程取消引用 NULL 指针时由 CPU 生成的错误......该机制与该语言定义的 C++ 异常是分开的。

在您的示例中,当 C++ 程序throws出现异常时,这完全由编译器生成的代码和语言运行时库处理,不需要内核调用,处理器也不会产生硬件故障。

于 2013-02-06T20:57:08.697 回答
8

您正在谈论两个完全不同的异常过程。

第一个是由操作系统提供的。在 Windows 中,您可以使用__try__except处理它们。

第二个由 C++ 编译器提供,不以任何方式涉及操作系统。

于 2013-02-06T20:54:34.917 回答
7

由于我只知道一两个用 C++ 编写的操作系统,而我更了解的操作系统根本没有正式使用异常,这几乎排除了操作系统抛出的异常。

三个主要操作系统(Linux、Windows、MacOS X)以及所有形式的 Unix(AIX、Solaris、HP-UX 等)都是用 C 编写的,以及几乎所有其他非汇编语言编写的商用操作系统,所以不能抛出 C++ 类型的异常[这并不是说没有软件驱动的异常,只是它们不是你在 C++ 中用“try/catch”捕获的异常类型,没有某种翻译]。

在第一个示例中,操作系统肯定涉及[在我知道它们如何工作的所有操作系统中],因为除以零会在所有具有除法功能的机器上导致硬件异常,因此需要涉及操作系统。此外,无论是 C++、C 还是您在汇编程序中编写相同的东西,这都会以相同的方式编译和失败。对于大多数操作系统,它们会向程序发送信号,但由于您没有处理信号的代码,您的代码很可能会简单地中止,告诉操作系统发生了一些奇怪的事情并且它正在放弃,甚至懒得放松堆栈。

在第二种情况下,根本不涉及操作系统。对 main 的调用周围有一个“try-catch”块,上面写着“糟糕,有人扔了一些没有被抓住的东西,让我们退出吧”。涉及操作系统的唯一部分是“退出此进程”,这当然需要由操作系统完成,尽管我相信大多数操作系统,只是从“应用程序的起始地址”返回也将有同样的效果。

于 2013-02-06T20:56:39.290 回答