CLR如何将SEH异常映射到托管异常类型
托管异常处理构建在Windows操作系统的结构化异常处理之上,通常称为SEH。这意味着CLR了解如何在SEH和托管异常系统之间进行互操作,这是一个非常关键的点,因为SEH基于异常代码的概念,而托管异常处理则表示使用托管类型的异常。CLR相应地将SEH异常映射到托管异常,具体取决于引发SEH异常的方式和引发者。
注意:下面的讨论重点是运行在Windows操作系统上的桌面CLR。虽然讨论的目的是帮助理解这个概念,但是它使用了一些将来可能会改变的实现细节来说明。
托管代码中的同步异常(Synchronous exceptions)
当托管代码使用throw关键字引发异常时,它已经实例化了一个托管异常对象,该对象将表示引发的异常。这将传递给CLR,CLR在线程上设置一些与异常相关的状态,并调用Kernel32的RaiseException API来引发托管异常。此API的第一个参数是引发异常的SEH异常代码,CLR传递0xE0434F4D(托管异常SEH代码)。
这时,操作系统进入处理场景,开始在引发异常的线程堆栈上寻找SEH异常处理程序。CLR将其函数之一注册为OS的异常处理程序,以处理托管代码引起的异常。当它看到CLR SEH异常代码时,它知道正在引发托管异常,并继续查找线程状态以检索与异常相关的详细信息(例如,标识表示引发异常的托管异常对象)。
因此,在同步托管抛出的情况下,很容易将SEH异常映射到托管异常类型。
托管代码中的异步异常(Asynchronous exceptions)
简单地说,异步异常是在没有显式抛出的情况下引发的异常。如果执行算术操作(例如除以零异常)或使用可能导致访问冲突(AV)等异常的不安全托管代码,则在托管代码中可能会发生这种情况。异步异常的有趣之处在于,它们是使用它们唯一的SEH异常代码来表示的。例如AV用0xc000005表示,除以0(整数)用0xC0000094表示,除以0(浮点数)用0xC000008E表示,这里列出了常见的异常,异常代码值可以在WinNT.h中找到。
当在托管代码中引发此类异常时,操作系统再次开始在引发异常的线程堆栈上查找异常处理程序。当调用CLR的异常处理程序时,它知道所讨论的异常不是托管代码同步抛出的,因为异常代码不是CLR SEH异常代码。因此,它不再查找与异常相关的详细信息的线程状态,而是将SEH异常映射到一个托管异常类型。例如,除以零异常(整数和浮点)使用System.DivideByZeroException表示。
同样,当在托管代码中生成真正的AV时,它的异常代码为0xc000005。由于托管代码具有空引用的概念,因此运行时很少再进行检查来确定AV是否表示尝试使用空引用。如果是,则映射到System.NullReferenceException。否则,它将映射到System.AccessViolationException类型(在v2.0和更高版本的运行时中)。
在Native代码中引发异常

假设Zoo抛出了一个未在其中处理的Native异常,则该异常将向上传播,因为OS沿着堆栈向上移动,寻找异常的潜在处理程序。在这种情况下,由于堆栈上的下一个帧是Bar,而Bar是受管理的,因此操作系统最终会调用CLR的异常处理程序。由于SEH异常来自Native代码,因此它可能有任何异常代码。例如,它可以是一个C++异常(它具有SEH 0X06D7363的异常代码),或者它可以是一个特定于应用程序的SEH异常代码。关键在于CLR不知道存在的所有SEH异常代码(并且将来会被创建)。从映射到特定托管异常类型的角度来看,只有现有的子集是有意义的。
因此,当CLR的异常处理程序看到Native异常时,它将尝试将最常见的SEH异常代码映射到它们相应的托管异常类型(如前面用一些示例解释的那样)。对于运行时未标识的任何其他SEH异常代码,它将映射到System.runtime.InteropServices.SEH exception类型。
接下来会发生什么?
- 当操作系统从特定SEH异常的抛出点为堆栈上的第一个托管帧调用CLR的异常处理程序(假设堆栈上没有上下文转换)时,此映射仅完成一次。
- 由于此映射是基于SEH异常代码完成的,因此CLR知道给定的托管异常实例是否表示真正的Native SEH异常。例如,CLR知道System.AccessViolationException实例是否表示真正的AV或是托管代码引发的常规托管异常。为什么这很重要?好吧,当CLR确定了异常的损坏严重性时,它就会这样做!
映射完成后,CLR将开始查找异常处理程序的常规异常处理过程。
CLR如何将SEH异常映射到托管异常类型的更多相关文章
- c# 捕获非托管异常
在.NET 4.0之后,CLR将会区别出一些异常(都是SEH异常),将这些异常标识为破坏性异常(Corrupted State Exception).针对这些异常,CLR的catch块不会捕捉这些异常 ...
- Struts2拦截器之ExceptionMappingInterceptor(异常映射拦截器)
一.异常拦截器是什么? 异常拦截器的作用是提供一个机会,可以设置在action执行过程中发生异常的时候映射到一个结果字符串而不是直接中断. 将异常整合到业务逻辑中,比如在分层系统的调用中可以从底层抛出 ...
- Struts2学习第四天——全局结果,动态结果及异常映射
1.异常映射的配置 当Action方法出错时Struts会返回异常错误信息页面,这种页面方式是不友好的,可以使用try-catch捕捉异常,然后在catch块中返回对应的错误页面.这种为单个<a ...
- SpringBoot2.0 基础案例(03):配置系统全局异常映射处理
一.异常分类 这里的异常分类从系统处理异常的角度看,主要分类两类:业务异常和系统异常. 1.业务异常 业务异常主要是一些可预见性异常,处理业务异常,用来提示用户的操作,提高系统的可操作性. 常见的业务 ...
- SimpleMappingExceptionResolver异常映射
转自:https://blog.csdn.net/qqqqqq654/article/details/65767701 SimpleMappingException异常映射 当异常发生时,我们可以将它 ...
- Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程
SpringMVC 拦截器 Spring MVC也可以使用拦截器对请求进行拦截处理,可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口中的三个方法,也可以 ...
- 三:SpringBoot-配置系统全局异常映射处理
三:SpringBoot-配置系统全局异常映射处理 1.异常分类 1.1 业务异常 1.2 系统异常 2.自定义异常处理 2.1 自定义业务异常类 2.2 自定义异常描述对象 2.3 统一异常处理格式 ...
- springmvc——基于xml的异常映射和基于注解的异常映射
SpringMVC提供了基于XML和基于注解两种异常映射机制.这两种异常映射不能够只使用一个,他们需要一起使用.因为有些异常是基于注解异常映射捕获不到的. 在springmvc中,一个请求如果是由&l ...
- CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段
编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32(); // a = 0 a = 1 ...
随机推荐
- Akka-CQRS(9)- gRPC,实现前端设备与平台系统的高效集成
前面我们完成了一个CQRS模式的数据采集(录入)平台.可以预见:数据的产生是在线下各式各样的终端系统中,包括web.桌面.移动终端.那么,为了实现一个完整的系统,必须把前端设备通过某种网络连接形式与数 ...
- 软件测试人员必备的Python知识图库
UI自动化测试(Python+Selenium等) 接口测试(Python requests等) 性能测试(Python Locust等) 安全性测试(Python Scapy等) 兼容性测试(Pyt ...
- spring中AspectJ的使用
目录 AspectJ: AOP术语 通知的类型 切入点表达式 基于xml的AspectJ编程 导入jar包 定义切面类 引入约束 AOP配置 基于注解的AspectJ编程 AspectJ: 什么是AO ...
- 2019 UCloudjava面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.UCloud等公司offer,岗位是Java后端开发,因为发展原因最终选择去了UCloud,入职一年时间了,也 ...
- Java自学-控制流程 If
Java的 If 条件语句 条件判断 示例 1 : if if(表达式1){ 表达式2: } 如果表达式1的值是true, 就执行表达式2 public class HelloWorld { publ ...
- window.requestAnimationFrame()的使用,处理更流畅的动画效果
https://blog.csdn.net/w2765006513/article/details/53843169 window.requestAnimationFrame()的使用 2016年12 ...
- 复盘一篇讲sklearn库学习文章(上)
认识 sklearn 官网地址: https://scikit-learn.gor/stable/ 从2007年发布以来, scikit-learn已成为重要的Python机器学习库, 简称sklea ...
- IDEA整合SVN遇到的坑
1.安装SVN客户端 注意客户端版本与汉化插件的版本匹配问题,否则汉化无效 2.安装客户端时第二项默认不安装记得要手动选择为安装,否则不会生成svn.exe,这个文件会在IDEA中配置 3.安装客 ...
- AD10生成Gerber文件详细步骤
参考:https://wenku.baidu.com/view/faf0363c195f312b3069a5d2.html
- C 是什么样的语言?
学习交流可加 微信读者交流①群 (添加微信:coderAllen) 程序员技术QQ交流①群:736386324 --- ==C 是什么样的语言?== 这个问题不要急于寻找问题的答案,而是应该先去考虑当 ...