【问题标题】:Do exceptions explicitly caught and handled cause switch to kernel mode?显式捕获和处理的异常是否会导致切换到内核模式?
【发布时间】:2015-04-07 17:25:56
【问题描述】:

从一本操作系统书上了解到异常(如算术溢出、未定义指令、无效内存访问)会导致cpu从用户态切换到内核态,以便操作系统处理异常

在高级编程语言中,我们可以捕获和处理程序中的默认异常(如上所述)或自定义异常,例如在 C++ 中,通过使用 trycatch,以及 Java 和 Python 中的类似结构。 我注意到在这种情况下,用户程序中会提供异常处理程序。

通过在用户程序中显式捕获和处理异常,

  • 默认异常是否仍会导致 cpu 从用户模式切换到内核模式,以便操作系统可以处理异常?

  • 自定义异常是否仍会导致cpu从用户态切换到内核态,以便操作系统处理异常?

谢谢! (如果需要特定于操作系统,那么 Linux)

【问题讨论】:

  • 不是真正相同类型的“异常”...
  • @Macmade;你的意思是?谢谢。
  • Tim,硬件异常总是由内核处理,由异常向量(基本上是一个函数指针数组)控制。然后内核向用户代码生成一个信号(在 Linux 上它实际上称为“信号”,在 Windows 上它是 SEH),通常您的语言的运行时库接收该信号并将其转换为该语言所称的异常,这就是程序员也可以随意扔。但硬件异常本来就不是语言异常,甚至有可能永远不会变成语言异常。
  • 例如,在 Linux 上的 C++ 代码中,硬件异常是通过安装信号处理程序来处理的,因为运行时库默认不提供。 (当然,内核异常处理程序仍然参与引发信号)
  • @BenVoigt:谢谢。在一本计算机体系结构的书中,它说算术溢出、未定义的指令和无效的内存访问将导致切换到内核模式。对我来说,它们听起来像是软件异常,那么它们是硬件异常吗? (有哪些书可以找出语言异常和非语言异常的区别?)

标签: linux exception exception-handling operating-system


【解决方案1】:

冒着过于简单化的风险,操作系统通常允许进程定义异常处理程序(Unix 中的信号处理程序)。硬件异常进入内核模式。然后内核模式处理程序查找用户模型处理程序并调用它。

语言运行时设置操作系统特定的异常处理程序,以便调用语言定义的异常处理程序。

【讨论】:

    【解决方案2】:

    Java virtual machine specification 表示当抛出异常时,它会寻找合适的异常处理程序:

    Java 虚拟机中的每个方法都可能与零或 更多异常处理程序。异常处理程序指定范围 偏移到实现该方法的 Java 虚拟机代码中 异常处理程序处于活动状态,描述异常的类型 异常处理程序能够处理,并指定 处理该异常的代码的位置。一个例外 如果指令的偏移量匹配异常处理程序 导致异常在异常的偏移范围内 处理程序和异常类型是相同的类或子类 异常处理程序处理的异常类。当一个 抛出异常,Java 虚拟机搜索匹配的 当前方法中的异常处理程序。如果匹配异常 找到handler,系统跳转到异常处理代码 由匹配的处理程序指定。

    如果没有找到这样的异常处理程序-它将complete abruptly

    如果执行 Java Virtual,方法调用会突然完成 方法中的机器指令导致 Java 虚拟机 抛出异常(§2.10),并且该异常未被处理 方法内。还执行了一个抛出指令 (§athrow) 导致显式抛出异常,如果异常是 未被当前方法捕获,导致突然的方法调用 完成。突然完成的方法调用永远不会返回 对其调用者的一个值。

    关于你的问题,当它突然完成时 - 控制权被传递回内核。

    【讨论】:

    • 唯一可以保证的是控制权被传递给最近的 finally 块或匹配的 catch 块。运行时是否征得内核的帮助以找到这些是特定于实现的。
    猜你喜欢
    • 2014-04-30
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 2010-09-10
    • 2011-07-29
    • 2016-12-26
    相关资源
    最近更新 更多